Documentation
¶
Overview ¶
Package auth provides AuthProvider implementations.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrMissingCredentials = errors.New("auth: missing credentials") ErrInvalidCredentials = errors.New("auth: invalid credentials") )
Errors returned by Authenticate.
Functions ¶
func IdentityFromContext ¶
IdentityFromContext returns the Identity attached by auth middleware.
func RequireAdmin ¶
RequireAdmin returns middleware that rejects any request whose authenticated Identity does not carry `IsAdmin = true`. Returns an RFC 7807 problem response:
- 401 if no Identity is attached (auth middleware was skipped). This signals a misconfiguration: admin routes must sit behind the auth middleware, not behind an anonymous-paths exception.
- 403 if an Identity is present but not admin.
Design choice: RequireAdmin depends only on the already-attached Identity. It does NOT re-authenticate — the auth provider is responsible for setting IsAdmin from its own rules (StaticProvider always sets true for static-key callers; OIDCProvider matches the `groups` claim against a configurable admin-groups list). Keeping this middleware ignorant of provider type means admin routes work identically under any auth provider.
Types ¶
type OIDCOption ¶
type OIDCOption func(*OIDCProvider)
OIDCOption configures an OIDCProvider.
func WithAdminGroups ¶
func WithAdminGroups(groups ...string) OIDCOption
WithAdminGroups lists group values that should be treated as admin. If empty, tokens are never admin (safe default). Matches against the "groups" or "roles" claim.
func WithOIDCAnonymousPath ¶
func WithOIDCAnonymousPath(prefix string) OIDCOption
WithOIDCAnonymousPath makes a path prefix unauthenticated.
type OIDCProvider ¶
type OIDCProvider struct {
// contains filtered or unexported fields
}
OIDCProvider validates OAuth2 / OpenID Connect Bearer tokens using standard OIDC Discovery. It works with any compliant provider: Dex (recommended for local dev), Keycloak, Ory Hydra, Okta, Auth0, etc.
On each request the provider:
- extracts the Bearer token
- verifies the signature and issuer via the provider's JWKS
- checks exp/nbf/iat
- validates the audience claim
- maps the token's "sub", "scope", and optional "groups" claims into a port.Identity
Tokens are not cached; go-oidc caches the JWKS internally.
func NewOIDCProvider ¶
func NewOIDCProvider(ctx context.Context, issuerURL, audience, clientID string, opts ...OIDCOption) (*OIDCProvider, error)
NewOIDCProvider constructs a provider that validates tokens from the given issuer URL and audience. Discovery is performed once at startup; a failure here prevents server start.
func (*OIDCProvider) Authenticate ¶
Authenticate verifies the token in the Authorization header.
func (*OIDCProvider) Middleware ¶
func (p *OIDCProvider) Middleware() func(http.Handler) http.Handler
Middleware enforces authentication on all non-anonymous paths.
type StaticOption ¶
type StaticOption func(*StaticProvider)
StaticOption configures a StaticProvider.
func WithAPISecret ¶
func WithAPISecret(secret string) StaticOption
WithAPISecret enables the reference-compatible `Authorization: sso-key <apikey>:<secret>` format. When the secret is empty, only the Bearer format is accepted. The SDKs produced against the reference RA send `sso-key`; deployments that want SDK compatibility must configure a secret here.
func WithAnonymousPath ¶
func WithAnonymousPath(prefix string) StaticOption
WithAnonymousPath marks a URL-path prefix as unauthenticated. Handlers can still call IdentityFromContext; it will return (nil, false). Typically used for /admin/health and /v1/agents/* public reads.
func WithStaticSubject ¶
func WithStaticSubject(s string) StaticOption
WithStaticSubject sets the subject reported for authenticated requests. Defaults to "static-user".
type StaticProvider ¶
type StaticProvider struct {
// contains filtered or unexported fields
}
StaticProvider is a quickstart AuthProvider that accepts a single static API key configured via the server's YAML config. Supports two Authorization header formats so ANS SDKs and simple curl-based tooling both work against the same deployment:
`Authorization: Bearer <apiKey>` — simple bearer token. The ans-native format used by the demo scripts. Matched against `apiKey`.
`Authorization: sso-key <apiKey>:<apiSecret>` — the reference RA's format (see the reference `check_api_key` helper). The case-insensitive "sso-key " prefix is optional — a bare `apiKey:apiSecret` pair in the Authorization header is also accepted, matching the reference regex `^(?:sso-key\s+)?([^:]+):(.+)$`. Matched against `apiKey` + `apiSecret` (both must be configured).
All comparisons are constant-time to resist timing side-channels.
Do not use StaticProvider in production. Use OIDCProvider instead.
func NewStaticProvider ¶
func NewStaticProvider(apiKey string, opts ...StaticOption) *StaticProvider
NewStaticProvider creates a StaticProvider with the given key.
func (*StaticProvider) Authenticate ¶
Authenticate accepts either format:
- `Authorization: Bearer <apiKey>` — matched against the configured apiKey.
- `Authorization: sso-key <apiKey>:<apiSecret>` (prefix optional, case-insensitive) — matched against apiKey + apiSecret. Only accepted when a non-empty apiSecret is configured.
Missing/malformed header → ErrMissingCredentials. Header present but neither format matches → ErrInvalidCredentials.
func (*StaticProvider) Middleware ¶
func (p *StaticProvider) Middleware() func(http.Handler) http.Handler
Middleware returns an http.Handler middleware enforcing authentication. Requests to anonymous path prefixes pass through without an Identity.