feat: canonical shared runtime-profiles config with typed auth refs (#19)
Rework the JSON runtime-profile config from the earlier ad-hoc schema (profiles + token_env) to the canonical single-file model in #19, so every LLM launcher can reference one shared Gitea profiles file instead of duplicating GITEA_USER_*/GITEA_PASS_* blocks or embedding tokens. Canonical schema (gitea_config.py): - top-level "version" (1) + "profiles" map. - each profile: base_url, username, default_owner, execution_profile, and a typed auth reference: { "type": "keychain", "id": "..." } -> macOS keychain (security(1)) { "type": "env", "name": "..." } -> named environment variable - inline "token"/"password" keys are rejected (never accepted or echoed). - select via GITEA_MCP_CONFIG (path) + GITEA_MCP_PROFILE (name). gitea_auth integration: - get_profile() overlays env over the selected profile (env wins; JSON fills the rest); profile_name <- execution_profile; token_source_name <- the non-secret auth reference name (env var name or "keychain:<id>"); now also surfaces username + default_owner. - get_auth_header() resolves the profile's auth reference (env/keychain) as a token fallback after explicit env tokens; a ConfigError there fails closed. Security / safety: - Secrets referenced only (keychain id / env name); token values never stored in or returned as metadata. Errors never print file contents, tokens, or passwords (JSONDecodeError context suppressed). - Missing file / invalid JSON / unsupported version / unknown-or-unset profile / unresolvable secret reference all raise a clear, safe ConfigError. - No network calls during config parsing; keychain lookup is on-demand and injectable for tests. - Backwards compatible: GITEA_MCP_CONFIG unset => legacy env-only mode (existing get_profile/get_auth_header tests unchanged). Docs: README canonical-profile + thin-launcher (Claude/Gemini/Codex) sections and a migration note away from duplicated GITEA_PASS_* blocks; .env.example and gitea-mcp.example.json updated to the canonical shape (safe placeholders only). Tests: tests/test_config.py (31 cases) — legacy env-only, JSON selection, multiple profiles, missing/unset profile, invalid JSON, unsupported version, env-override precedence, keychain + env auth-reference parsing and resolution, missing-secret errors, inline token/password redaction, and no-network parse. Refs #10. Completes the closed #19 (env-based profiles) by adding the canonical shared-file model. Supersedes this PR's earlier simpler JSON schema. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+29
-18
@@ -1,24 +1,35 @@
|
||||
{
|
||||
"version": 1,
|
||||
"profiles": {
|
||||
"dev": {
|
||||
"base_url": "https://gitea.dev.example",
|
||||
"profile_name": "gitea-author",
|
||||
"token_env": "GITEA_TOKEN_DEV",
|
||||
"owner": "Scaled-Tech-Consulting",
|
||||
"repo": "Gitea-Tools",
|
||||
"allowed_operations": ["read", "pr.create"],
|
||||
"forbidden_operations": ["merge"],
|
||||
"audit_label": "dev-author"
|
||||
},
|
||||
"prod-readonly": {
|
||||
"prgs": {
|
||||
"base_url": "https://gitea.prgs.cc",
|
||||
"profile_name": "gitea-readonly",
|
||||
"token_env": "GITEA_TOKEN_PROD",
|
||||
"owner": "Scaled-Tech-Consulting",
|
||||
"repo": "Gitea-Tools",
|
||||
"allowed_operations": ["read"],
|
||||
"forbidden_operations": ["merge", "approve", "request_changes"],
|
||||
"audit_label": "prod-ro"
|
||||
"username": "jcwalker3",
|
||||
"auth": {
|
||||
"type": "keychain",
|
||||
"id": "prgs-gitea-token"
|
||||
},
|
||||
"default_owner": "Scaled-Tech-Consulting",
|
||||
"execution_profile": "personal-prgs"
|
||||
},
|
||||
"mdcps": {
|
||||
"base_url": "https://gitea.dadeschools.net",
|
||||
"username": "913443",
|
||||
"auth": {
|
||||
"type": "keychain",
|
||||
"id": "mdcps-gitea-token"
|
||||
},
|
||||
"default_owner": "Contractor",
|
||||
"execution_profile": "mdcps"
|
||||
},
|
||||
"prgs-env": {
|
||||
"base_url": "https://gitea.prgs.cc",
|
||||
"username": "jcwalker3",
|
||||
"auth": {
|
||||
"type": "env",
|
||||
"name": "GITEA_TOKEN_PRGS"
|
||||
},
|
||||
"default_owner": "Scaled-Tech-Consulting",
|
||||
"execution_profile": "personal-prgs"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user