fix: load ./.env only when private and owned, add --env-file and AEGIS_ENV_FILE (SEC-04)
This commit is contained in:
1 parent
7307214ab6
commit
79aa4f7fc0
11 files changed
+360
-20
No files matched your search
+22
-3
@@ -1,9 +1,28 @@
|
||||
# Configuration
|
||||
|
||||
All settings are environment variables. They are read case-insensitively from the process
|
||||
environment and from a `.env` file in the working directory (the environment wins). Unknown
|
||||
variables are ignored. A blank value (`KEY=` in `.env`) counts as unset for the optional
|
||||
secrets, URLs and paths. List values accept commas or whitespace as separators.
|
||||
environment and from an env file (the environment always wins). Unknown variables are ignored.
|
||||
A blank value (`KEY=` in the env file) counts as unset for the optional secrets, URLs and
|
||||
paths. List values accept commas or whitespace as separators.
|
||||
|
||||
## Which env file is read
|
||||
|
||||
The env file is never trusted just because it sits in the working directory: MCP clients start
|
||||
stdio servers inside the project they work on, which can be a cloned repository carrying a
|
||||
planted `.env` that switches off secret masking or the audit log or points `GITEA_URL` at
|
||||
another host. The file is chosen in this order:
|
||||
|
||||
1. `--env-file PATH` of `serve` (and `setup`): used as given. It must exist and be a regular
|
||||
file.
|
||||
2. The `AEGIS_ENV_FILE` environment variable: same rules.
|
||||
3. `./.env`, but only when it is a regular file (not a symlink), owned by the user running the
|
||||
server, with no group or other permissions (mode 0600, which `setup` writes). Otherwise it is
|
||||
ignored and one warning goes to stderr that says why and how to fix it:
|
||||
`chmod 600 .env`, or pass `--env-file`.
|
||||
|
||||
Real environment variables take precedence over every file. A missing `./.env` is silent.
|
||||
Containers pass settings as environment variables (`env_file:` in compose), not through the
|
||||
working directory.
|
||||
|
||||
`.env.example` is the annotated template. `uv run aegis-gitea-mcp setup` fills one in for you
|
||||
(see [getting-started.md](getting-started.md)). Secret settings never appear in logs, errors or
|
||||
|
||||
@@ -29,7 +29,7 @@ Setup prompts for the Gitea URL and the token (hidden input). For unattended use
|
||||
| `--gitea-url` | Gitea base URL |
|
||||
| `--public-base-url` | Public https URL of this server. Enables registration of the OAuth application |
|
||||
| `--no-oauth` | Do not create the Gitea OAuth application |
|
||||
| `--env-file` | Env file to create or update (default `./.env`) |
|
||||
| `--env-file` | Env file to create or update (default `AEGIS_ENV_FILE`, else `./.env`) |
|
||||
| `--template` | Env template (default `./.env.example`, else the copy built into the package) |
|
||||
| `--yes` | Never prompt, and accept regenerating an OAuth client secret |
|
||||
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ Tampering
|
||||
| Query smuggling of credentials or Sudo | `token`, `access_token`, `sudo`, `_sudo` refused as query names (any case) | `gitea/encoding.py` |
|
||||
| Malformed arguments | JSON Schema validation (Draft 2020-12, `additionalProperties: false`) before anything runs; messages never echo values | `server.py` |
|
||||
| Store tampering or wrong key | Fernet (authenticated encryption) with an HKDF-SHA256 key; undecryptable store stops startup instead of being wiped; symlinks refused | `oauth/store.py` (rollback residual: SEC-13) |
|
||||
| Settings injection from a planted `.env` | none yet | `config.py` (SEC-04) |
|
||||
| Settings injection from a planted `.env` | `./.env` is loaded only when it is a regular file, not a symlink, owned by the user, mode 0600; otherwise ignored with a warning; `--env-file` or `AEGIS_ENV_FILE` name a file explicitly; the environment wins | `config.py` (`select_env_file`), `cli.py` |
|
||||
|
||||
Repudiation
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ Gitea's sanitized message, and the audit log has one event per call (see
|
||||
|
||||
| Message or exit | Cause and fix |
|
||||
|---|---|
|
||||
| Exit code 2, "GITEA_TOKEN" required (stdio) | stdio needs `GITEA_TOKEN`. Put it in the client's `env` block or in `.env` in the working directory the client starts the server in. |
|
||||
| Exit code 2, "GITEA_TOKEN" required (stdio) | stdio needs `GITEA_TOKEN`. Put it in the client's `env` block, or in an env file passed with `--env-file` (or `AEGIS_ENV_FILE`). A `.env` in the working directory counts only when it is a regular file you own with mode 0600. |
|
||||
| Warning "ignoring ./.env: ..." | The working directory's `.env` is a symlink, owned by someone else or accessible to group or others, so its settings are not loaded. Run `chmod 600 .env`, or pass `--env-file PATH`. See "Which env file is read" in [configuration.md](configuration.md). |
|
||||
| Exit code 2, "env file ... does not exist" | The file named by `--env-file` or `AEGIS_ENV_FILE` is missing or not a regular file. |
|
||||
| Exit code 2, refuses a non-loopback bind | `MCP_HOST` is not loopback and there is no `MCP_BEARER_TOKEN` or complete OAuth setup. Set one of them, or bind `127.0.0.1` behind a reverse proxy. |
|
||||
| Exit code 2, lists OAuth settings | `OAUTH_ENABLED=true` needs `GITEA_OAUTH_CLIENT_ID`, `GITEA_OAUTH_CLIENT_SECRET`, `TOKEN_ENCRYPTION_KEY` and `PUBLIC_BASE_URL`. |
|
||||
| Validation error naming a setting | See the rules in [configuration.md](configuration.md): URLs must be http(s) without credentials, `PUBLIC_BASE_URL` must be https, secrets need 32 characters, `OAUTH_SCOPES` accepts only granular scopes. |
|
||||
|
||||
Reference in new issue
Block a user