# auth Shared Go library with authentication primitives for all Shiny backend services. ## Shared Documentation @../docs/claude/architecture.md @../docs/claude/go-services.md @../docs/claude/conventions.md ## Library Information ### Purpose Single home for the `user`-header auth and secret-startup-guard code that was previously byte-identical-copied into every backend (the `auth` package and `cmd/service/secrets_guard.go`). Enforces ADR-0005 (HMAC-signed `user` header, keyless fail-open only in acctest) and ADR-0006 (fail closed when required secrets are missing in `staging`/`production`). ### Usage ```go import "gitea.unbound.se/shiny/auth" // Fail closed on missing deployed secrets before serving (ADR-0005/0006). if missing := auth.MissingDeployedSecrets(environment, map[string]string{ "USER_SIGNING_KEY": cfg.UserSigningKey, "INTERNAL_API_KEY": cfg.InternalAPIKey, }); len(missing) > 0 { log.Fatalf("refusing to start: missing secrets in %s: %v", environment, missing) } // Verify the gateway's signed user header and inject *User into the context. handler = auth.UserMiddleware([]byte(cfg.UserSigningKey))(handler) // Read the authenticated user downstream. user := auth.FromContext(ctx) if user.HasRole("admin") { /* ... */ } ``` ### Exported API - `UserMiddleware(signingKey []byte)` — HTTP middleware verifying the HMAC-signed `user` header; injects `*User` into the request context. - `FromContext(ctx) *User`, `User.HasRole(...) bool`, `ContextKey`/`UserKey`. - `MissingDeployedSecrets(environment string, secrets map[string]string) []string` — returns the sorted names of secrets that are empty in `staging`/`production` (nil for any other environment, e.g. `development`/acctest). ### Conventions Standard Shiny library scaffolding: `gofumpt`/`goimports -local`, golangci-lint, gitleaks and conventional-commit checks via pre-commit; coverage-regression gate in CI (`.testcoverage.yml`); releases auto-tagged from conventional commits by the shared Release workflow. Bump the consuming services' `go.mod` after a release. A breaking change to the signed-header or secret-guard contract is a cross-service change — see ADR-0005/0006 before changing it.