fix(cfg,token): remove hardcoded brand identity literals#6
Merged
Conversation
…1/002/003, TD-CFG-001/002, TD-TEST-001) The JWT iss claim, JWT aud override, TrustDomain default, DBPath default, and config search paths all hardcoded brand-coupled string literals into source. The "no hardcoded identity values" rule says these belong in cfg, not in literals. This commit removes every brand literal from the production surface and the test surface in one pass. Production code: - iss: hardcoded "agentauth" -> driven by cfg.Issuer (env AA_ISSUER). Issuer enforcement moved out of TknClaims.Validate() (now pure structural) into TknSvc.Verify() where cfg is available. Empty cfg.Issuer skips the check, mirroring the documented Audience contract — operator opt-in. - aud: cfg.go:96 override "" -> "agentauth" deleted. Audience now honors its own documented "empty = skip" contract. No brand-coupled default. - TrustDomain default: "agentauth.local" -> "agentwrit.local" - DBPath default: "./agentauth.db" -> "./data.db" - Config search paths: /etc/agentauth/config -> /etc/broker/config, ~/.agentauth/config -> ~/.broker/config, generated config file header updated. - Package doc comment in tkn_claims.go updated to stop teaching that the issuer is "always 'agentauth'". Test surface: - All test fixtures across cfg/, token/, authz/, deleg/, admin/, identity/, mutauth/ updated to use brand-neutral test values: test-issuer for cfg, test.local for trust domain, spiffe://test.local/... for SPIFFE URIs. - Test assertions that locked in the hardcoded literals (cfg_test.go, tkn_svc_test.go, val_mw_test.go) now drive from fixture cfg, not literals. - TestLoad_AudienceDefault now asserts empty-when-unset (skip contract), not "agentauth"-when-unset. - TestLoad_DBPathDefault now asserts ./data.db. Root cause: IssuerURL was an OIDC-coupled cfg field stripped during the open-core split. The strip removed the field, the validation, AND the config-driven tests (tombstone preserved at internal/token/tkn_svc_test.go:521), but the validation was replaced with a hardcoded literal "agentauth" rather than left configurable. The general JWT iss claim is independent of OIDC and core still needs it — this commit restores configurability without re-coupling to OIDC. Standing rule added: ~/.claude/CLAUDE.md "No Hardcoded Identity Values — Universal, Non-Negotiable" (global, all projects). Validation: go build ./..., go vet ./..., gofmt -l, go test ./internal/... all green. 14/14 internal packages pass. Marks RESOLVED in TECH-DEBT.md: - TD-TOKEN-001, TD-TOKEN-002, TD-TOKEN-003 - TD-CFG-001, TD-CFG-002 - TD-TEST-001 Full audit at .plans/reviews/2026-04-10-hardcoded-identity-audit.md.
devonartis
added a commit
that referenced
this pull request
Apr 10, 2026
Catches docs up with the configuration defaults landed in PR #6 (TD-TOKEN-001, TD-CFG-001, TD-CFG-002) and PR #7 (TD-010). Docs were previously teaching the old hardcoded brand values in example JWT payloads, SPIFFE URIs, filesystem paths, and env var defaults. Now they reflect the current defaults as shipped. Direct push to develop (not PR) per explicit user instruction — this is documentation chasing production defaults, not new code. No Go source changes. Sweep patterns (bulk sed across docs/**/*.{md,yaml,yml,svg}): - agentauth.local -> agentwrit.local (matches cfg.TrustDomain default) - agentauth.db -> data.db (matches cfg.DBPath default) - /etc/agentauth/ -> /etc/broker/ (matches cfg.configfile.go search path) - /var/lib/agentauth/ -> /var/lib/broker/ (consistent data-dir naming) - ~/.agentauth/ -> ~/.broker/ (matches cfg.configfile.go home fallback) - "iss": "agentauth" -> "iss": "agentwrit" (example JWT payloads) - "aud": "agentauth" -> "aud": "agentwrit" (example JWT payloads) - AgentAuth -> AgentWrit (brand prose) - agentauth (bare) -> agentwrit (brand prose) - AGENTAUTH -> AGENTWRIT (any uppercase) Preserved (not changed): - github.com/devonartis/agentauth — Go module path + GitHub clone URLs (getting-started-user.md lines 74, 104). Module path rename is gated on the GitHub repo rename, which is separate work. - CHANGELOG historical entries (not touched) - tests/*/evidence/*.md historical records (not touched — they're in tests/ not docs/, so the sweep didn't reach them anyway) Renames: - docs/agentauth-explained.md -> docs/agentwrit-explained.md Targeted updates: - docs/credential-model.md:154 — the "hardcoded adminTTL = 300, see TD-010" text replaced with the new reality: "5 minutes default, operator-configurable via AA_ADMIN_TOKEN_TTL." TD-010 is now RESOLVED in TECH-DEBT.md so the reference was stale. Scope: ~20 doc files + 1 file rename. No code, no tests, no scripts.
devonartis
added a commit
that referenced
this pull request
Apr 12, 2026
Includes: - PR #6: hardcoded identity audit fixes (TD-TOKEN-001/002/003, TD-CFG-001/002, TD-TEST-001) - PR #7: adminTTL → cfg.AdminTokenTTL (TD-010) - PR #8: aactl → awrit binary rename (TD-CLI-001) - PR #11: docs audit P1/P2 corrections + docs-layout-archon-style sweep - PR #12: runtime rebrand alignment — problemdetails URN, obs metrics, awrit init config path (TD-RUNTIME-001, TD-OBS-001, TD-CLI-002), GitHub repo rename agentauth → agentwrit, Go module path rename, README/CONTRIBUTING/docs sweep, CI brand-alignment gate - Direct-to-develop: brand sweep docs (684083b) Stripped 16 dev-only paths: MEMORY.md, FLOW.md, TECH-DEBT.md, MEMORY_ARCHIVE.md, CLAUDE.md, AGENTS.md, COWORK_SESSION.md, COWORK_DOCS_AUDIT.md, .plans/, .claude/, .agents/, audit/, adr/, .vscode/, .active_module, generate_pdf.py.
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes every brand-coupled string literal from
internal/cfg/andinternal/token/(production + tests). The JWTissclaim, the JWTaudoverride, theTrustDomaindefault, theDBPathdefault, and the FHS config search paths all hardcoded"agentauth"(or"agentauth.local","./agentauth.db",/etc/agentauth/...) into source. This PR makes them configurable, defaults them to brand-neutral values, and migrates the test surface to brand-neutral fixture values in one pass.Resolves: TD-TOKEN-001, TD-TOKEN-002, TD-TOKEN-003, TD-CFG-001, TD-CFG-002, TD-TEST-001 (all marked RESOLVED in
TECH-DEBT.md).What changed
Production:
cfg.Issuerfield added (envAA_ISSUER); empty = skip issuer enforcement onVerify()(mirrors documented Audience contract)TknClaims.Validate()(now pure structural — sub, jti, exp, nbf only) intoTknSvc.Verify()where cfg is availablecfg.go:96Audienceoverride"" -> "agentauth"deleted; honors documented"empty = skip"contractTrustDomaindefault"agentauth.local"->"agentwrit.local"DBPathdefault"./agentauth.db"->"./data.db"/etc/agentauth/config->/etc/broker/config,~/.agentauth/config->~/.broker/config# AgentAuth Configuration-># Broker Configurationtkn_claims.goupdated (no more "the issuer is always 'agentauth'")Tests:
cfg/,token/,authz/,deleg/,admin/,identity/,mutauth/updated to use brand-neutral values:Issuer: "test-issuer",TrustDomain: "test.local",spiffe://test.local/...tkn_svc_test.goandval_mw_test.gonow drive from fixture cfg instead of literalscfg.Cfg{}literal constructions intkn_svc_test.go,deleg_svc_test.go,admin_svc_test.gonow includeIssuer: "test-issuer"TestLoad_AudienceDefaultnow asserts empty-when-unset (the actual contract)TestLoad_DBPathDefaultnow asserts./data.dbRoot cause
IssuerURLwas an OIDC-coupled cfg field stripped during the open-core split. The strip removed the field, the validation, AND the config-driven tests (tombstone preserved atinternal/token/tkn_svc_test.go:521), but the validation was replaced with a hardcoded"agentauth"literal rather than left configurable. The general JWTissclaim is independent of OIDC and core still needs it. This PR restores configurability without re-coupling to OIDC.Full audit at
.plans/reviews/2026-04-10-hardcoded-identity-audit.md.Standing rule
~/.claude/CLAUDE.mdnow contains "No Hardcoded Identity Values — Universal, Non-Negotiable" as a global rule across all projects. Identity-shaped string literals in source code are now non-negotiable findings.Test plan
go build ./...cleango vet ./...cleangofmt -l internal/ cmd/returns emptygo test ./internal/...— 14/14 internal packages pass locallyformat,build,vet,lint,unit-tests,unit-tests-race,gosec,govulncheck,go-mod-verify,contamination,docker-build,smoke-l25,sbomall greengates-passedaggregator green (required for merge)AA_ISSUER=foo, issue a token, verifyissclaim is"foo". Boot withoutAA_ISSUER, verify the iss check is skipped on Verify.AA_ISSUER, but that's fine — empty = skip)What this PR does NOT do
aactl initinteractive flow (separate work)docs/api.md,docs/common-tasks.md,docs/foundations.md,docs/implementation-map.mdstill show"iss": "agentauth"— separate cleanup item)aactl->awritbinary (TD-CLI-001, separate PR)config-matrixCI job to verify tunables at runtime (deferred — flagged in the action plans for the next PR that adds a tunable)