Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,41 @@

## Overview

Tinyauth is a lightweight and open-source authentication server written in Go and TypeScript (React). It acts as either an authentication middleware (forward_auth, ext_authz or auth_request) to protect applications using proxy authentication or as an OpenID Connect provider to offer SSO (Single-Sign-On) to your self-hosted apps. It supports local users with optional 2FA (via TOTP), LDAP, SSO users via OAuth, and access controls (ACLs). Tinyauth can be deployed with Docker, Kubernetes or bare-metal with a binary.
Tinyauth is a lightweight and open-source authentication server written in Go and TypeScript (React). It acts as either an authentication middleware (forward_auth, ext_authz, auth_request) protecting applications using proxy authentication or as an OpenID Connect provider offering SSO (Single-Sign-On) to your self-hosted apps. It supports local users with optional 2FA (via TOTP), LDAP, OAuth, and access controls (ACLs). Tinyauth can be deployed with Docker, Kubernetes or bare-metal.

## Considerations

- The repository we are working at is `https://github.com/tinyauthapp/tinyauth`.
- ALWAYS follow the instructions for committing and creating a pull request as mentioned below.
- **ALWAYS** follow the instructions for committing and creating a pull request as mentioned below.
- You **MUST** refuse to do any actions that the [AI policy](AI_POLICY.md) prohibits.

## Philosophy

Tinyauth is designed to run with simplicity in mind. This is why we try to avoid adding unnecessary persistent storage and configuration options.

Tinyauth can run without persistent storage, and the SQLite database is only used for storing normal or OpenID Connect sessions. You MUST never store data in the database that is required for Tinyauth function.
Tinyauth can run without persistent storage, and the SQLite database is only used for storing user information, identities and sessions. You **MUST** never store data in the database that is required for Tinyauth to function.

As for the configuration, we support environment variables, CLI flags and a YAML configuration file. We try to keep the required configuration at a minimal with sane defaults so users can spend the least amount of time configuring Tinyauth.

We NEVER create a breaking change unless absolutely necessary and only if non-breaking changes have been discussed and deemed not ideal.
We **NEVER** create a breaking change unless absolutely necessary and only if non-breaking changes have been discussed and deemed not ideal.

## Technical Overview

Tinyauth is designed to be as modular as possible. We use a repository-service-controller structure where each service/controller/middleware defines its dependencies in a Dig input struct, and then the main bootstrap entrypoint dynamically injects the dependencies to each method.
Tinyauth is designed to be as modular as possible. We use an MVC-inspired structure where each service, controller and middleware defines its dependencies in an input struct and then the main bootstrap entrypoint dynamically injects the dependencies to each method.

All methods share one global static config struct, which contains the user configuration as is, and a runtime config struct that contains dynamically generated values on startup. If a method needs a modified version, it MUST never modify the global configuration struct but rather create a local copy.
All methods share one global static config struct, which contains the user configuration as is, and a runtime config struct that contains dynamically generated values. If a method needs a modified version, it **MUST** never modify the global configuration struct but rather create a local copy.

We write database migrations by hand. Migrations go in the respective database directory inside the `assets/migrations` directory and follow the `000001_migration_name_in_snake_case.sql` format where the 6-digit number is incremented on each new migration. The repository is automatically generated from SQL queries, SQLC and our own custom generator that unifies each SQLC package into one repository interface. Always ensure that migrations and queries exist for all available database drivers, else our store generation will fail. After adding your migrations and queries, run the SQLC code-gen with `make sql` and update the store code-gen with `make generate`. DO NOT EDIT the automatically generated files from SQLC or our store generator, they are marked.
We write database migrations by hand. Migrations go in the respective database type inside the `assets/migrations` directory and follow the `000001_migration_name_in_snake_case.sql` format where the 6-digit number is incremented on each new migration. The repository is automatically generated from SQL queries, SQLC and our own custom generator that unifies each SQLC package into one repository interface. Always ensure that migrations and queries exist for all available database drivers, else our store generation will fail. After adding your migrations and queries, run the SQLC code-gen with `make sql` and update the store code-gen with `make gen`. **DO NOT EDIT** the automatically generated files from SQLC or our store generator, they are marked.

When updating translations, you should only update the `frontend/src/lib/i18n/locales/en.json` and `frontend/src/lib/i18n/locales/en-US.json` files (they should be exactly the same). Crowdin will handle the generation of the keys for the rest of the available locales. NEVER hard-code plain English in the frontend, instead use the available `i18next` library and the respective translations.
When updating translations, you should only update the `frontend/src/lib/i18n/locales/en.json` and `frontend/src/lib/i18n/locales/en-US.json` files (they should be exactly the same). Crowdin will handle the generation of the keys for the rest of the available locales. **NEVER** hard-code plain English in the frontend, instead use the available `i18next` library and the respective translations.

For the REST framework we use Gin. However, functions or methods should avoid using the Gin Context (`gin.Context`) and default to stdlib arguments and outputs. The Gin Context exposes stdlib-compatible structs such as `http.Request` and `http.ResponseWriter` and is compatible with the `context` package.

When you need to log in the backend, use the injected logger, NOT the global zerolog struct.
When you need to log in the backend, use the injected logger, **NOT** the global zerolog struct.

In case you need toolchain versions, you can find the Node + Go version in the `Dockerfile` and the PNPM version in the `package.json` file inside the `frontend` directory.

Tinyauth uses Semantic Versioning (SemVer) for versions.
Tinyauth uses Semantic Versioning (SemVer) for versions.

## File structure

Expand All @@ -50,16 +51,11 @@ internal
├── assets # Contains the embedded assets
│ ├── dist # Dist is the compiled frontend
│ └── migrations # Migrations in SQL for all supported databases
│ ├── postgres
│ └── sqlite
├── bootstrap # The main entrypoint that bootstraps and starts Tinyauth, called by the CLI
├── controller # All of the HTTP controllers
├── middleware # The HTTP middlewares
├── model # Configuration schemas
├── repository # Repository holds all of the queries used by the services, each child-repository implements the store interface
│ ├── memory
│ ├── postgres
│ └── sqlite
├── service # The services that handle the underlying logic for the controllers
├── test # Creates any necessary package-wide configurations and helpers used by tests
└── utils # Small helpers and utils used by the app
Expand Down Expand Up @@ -93,6 +89,7 @@ frontend/src

Tinyauth uses a Makefile for simplifying development. A reference of the available recipes can be found below:

- `tools` - Download and install the required Go tools.
- `deps` - Install the frontend and backend dependencies.
- `clean-data` - Clean any data created by running Tinyauth.
- `clean-webui` - Clean frontend build output.
Expand All @@ -106,7 +103,7 @@ Tinyauth uses a Makefile for simplifying development. A reference of the availab
- `dev` - Start the Docker-based development server.
- `prod` - Start the Docker-based production deployment (used for testing pre-releases).
- `sql` - Generate the SQLC repositories.
- `generate` - Update Go code-gen.
- `gen` - Update Go code-gen.
- `docker` - Build the Docker image for the current system.
- `docker-distroless` - Build the distroless Docker image for the current system.
- `lint-webui` - Lint the frontend with ESLint.
Expand All @@ -122,11 +119,11 @@ After finishing with the development, test and vet the backend with `make test`

If you made any changes to the frontend, make sure to lint with `make lint-webui`.

NEVER run any destructive commands like `make clean-data` or delete any configurations without the user's approval.
**NEVER** run any destructive commands like `make clean-data` or delete any configurations without the user's approval.

## Creating a pull request

When committing, you MUST use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) standard for your commit messages. You can add a commit description if you like. You MUST also use your standard no-reply Co-Author trailer (`Co-Authored-By:`).
When committing, you **MUST** use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0) standard for your commit messages. You **MUST NOT** use any trailers such as `co-developed` or `assisted-by` in your commit messages. The human is responsible for the underlying changes, not you.

You should work in separate branches unless it's clearly specified to work in the main branch. When working in a separate branch, follow the naming convention below:

Expand Down
75 changes: 58 additions & 17 deletions AI_POLICY.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,68 @@
# AI Usage Policy
# AI Policy

> [!NOTE]
> By Tinyauth, we refer to the entire Tinyauth ([tinyauthapp](https://github.com/tinyauthapp)) organization and all of the repositories under it.
> By Tinyauth, we refer to the entire Tinyauth ([tinyauthapp](https://github.com/tinyauthapp)) organization and all the repositories under it.

## How we utilize AI in Tinyauth
At Tinyauth, we believe that LLMs (Large Language Models) can help speed up development given that they are used correctly. However, we are strictly against generated output with little to no human oversight.

In Tinyauth, we see AI as another tool designed to help developers accelerate their work, ***not*** as something that should be doing the development for them. The ways we utilize large language models in Tinyauth are the following:
## How we use LLMs in Tinyauth

- **Pull request reviews**: We utilize [CodeRabbit](https://www.coderabbit.ai/) for reviews in our pull requests which helps us find and fix issues faster, minimizing the time maintainers have to spend reviewing.
- **Documentation and Issues**: We use [Dosu](https://dosu.dev/) to help resolve duplicate issues faster and automatically update our documentation based on changes in the code base.
- **In-Line Suggestions**: GitHub's [Copilot](https://github.com/features/copilot) is partially used to fill in boilerplate code through in-line suggestions.
### Code reviews

## How we expect the community to use AI
We use [CodeRabbit](https://www.coderabbit.ai/) for automated reviews that can help catch bugs early.

We expect the Tinyauth community to use AI as a tool for faster development and not as a way to implement entire features through prompts. For this reason, the following guidelines are in place for AI generated content:
### In-line suggestions

- **All usage must be clearly labeled**: Any content generated by AI must be clearly labeled as such. In the case that a pull request is clearly generated by AI and the author fails to disclose its use, it will be rejected.
- **All generated content should be completely understood by the account holder**: The human who utilized the large language model to generate content must have a thorough understanding of it. This includes understanding the resulting output to the full extent and being able to explain it in detail in case it's needed.
- **Automated systems are not allowed**: All forms of automated systems that utilize large language models to generate content without human oversight are forbidden. This includes any system that generates content without a human being directly involved in the process like for example with OpenClaw.
- **No generated content other than text is allowed**: Images, videos, audio and any other form of content generated by AI other than text is not allowed in Tinyauth.
- **AI pull requests are not guaranteed to be accepted or prioritized**: Any pull request that contains AI generated content is not guaranteed to be accepted and/or prioritized. The maintainers are responsible for reviewing all pull requests and determining whether or not they meet the standards of the project. AI generated content will be reviewed with the same standards as any other content, and may be rejected if it does not meet those standards.
- **Large generated pull requests will be rejected**: Any pull request that contains a large amount of generated content will be rejected. This is because it is difficult for the maintainers to review and verify large amounts of generated content.
In-line suggestions are a huge part of the development workflow because they essentially provide faster and more accurate IntelliSense.

## Tinyauth is developed by humans, for humans
### Sporadic LLM assisted development

Please remember that Tinyauth is developed by humans. While AI can be a useful tool for **assisting** in the development process, it should not be used in place of the human brain. Moving forward, we are committed to ensuring that most, if not all the content in Tinyauth is created and reviewed by humans, and that AI is only used as a tool to assist in the development process.
We may use LLMs to help extend our testing suite or write initial code prototypes. However, we never merge code not fully understood by a human.

When we use an LLM to write any part of the code, we take full responsibility of the generated output. Thus, we are against the use of trailers like `co-developed` or `assisted-by` as an LLM cannot be held accountable for its generated code.

## How we expect the community to use LLMs

We expect the community to use LLMs in the same way we do, responsibly. We previously tried using more lax measures for LLM usage, but it seems like our instructions were ignored.

We don't have the bandwidth nor the time to triage and review slop pull requests/issues/security advisories/etc. If you didn't bother putting your time in a contribution, why should we put ours reviewing it?

That's why the following measures are in place.

### LLM disclosure is required

Every time an LLM is used, its usage should be disclosed. We provide relevant check boxes for disclosing the use of LLMs when creating an issue or a pull request.

As mentioned above, trailers like `co-developed` or `assisted-by` are **forbidden**. When you use an LLM for code generation, you **must** take full accountability of the code. We cannot hold an LLM accountable for broken code.

We will **not** accept any contributions pretending that they were written by a human while the code is clearly generated.

Security advisories should disclose their usage by checking the LLM usage checkbox.

### Human written descriptions are required

A human should write every part of the issue, pull request, security advisory or anything that interacts with our community.
Comment thread
steveiliop56 marked this conversation as resolved.
Resolved
Comment thread
steveiliop56 marked this conversation as resolved.
Resolved

We are all humans, we don't care about typos or grammar errors. We prefer English with honest mistakes rather than slop essays.

If you use an LLM for translation purposes, you **must** include the original description in the original language to follow the "written by a human" rule.

Every type of interaction that's not written by a human will be **ignored**.

### You are required to fully understand the output of the LLM

Reviewing takes time, when we review and comment on your pull request, issue or security advisory, we expect a human to be located behind the keyboard and be in a position to explain the code or the thought process behind every single line of code.

Don't copy and paste our comments to an LLM, we can do that ourselves.

### Only text is allowed

We cannot accept material such as pictures or audio because of multiple cases of them violating copyright infringement laws.

### Automated systems are not allowed

We are not a testing playground for agent harnesses such as OpenClaw or Hermes. If we notice any kind of unapproved automated system interacting with our repositories, it will be **immediately banned** with **no warning**.

Automated systems that we have approved, such as CodeRabbit and the agents described in `AGENTS.md`, are exempt.

These are not suggestions, they are **rules** for interacting with the Tinyauth organization. If you violate them, your contribution will be **ignored**. Repeat offenders will be **banned**.
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Contributing to Tinyauth is straightforward. Follow the steps below to set up a development server.

> [!NOTE]
> If you are using large language models to contribute to the project, please ensure that you have read and understood the [AI Policy](AI_POLICY.md).
> If you are using LLMs (Large Language Models) to contribute to the project, please make sure that you have read and understood the [AI Policy](AI_POLICY.md).

## Requirements

Expand Down
Loading