Documentation
¶
Overview ¶
The credential policy, from tasksd's own environment.
The CHECK itself — keys, issuer, audience, the header contract — is hanzoai/authz/edge. This file is only the part that is genuinely tasksd's: which environment variables the values come from.
A reader used to live here, and it had two defects a shared one does not: it verified against EVERY key in the published set rather than the one the token's `kid` named, so a token naming key A was accepted on a signature from key B; and its issuer comparison was conditional on the configured issuer being non-empty, so an unset TASKSD_JWT_ISSUER accepted tokens from anyone instead of failing closed.
Package auth — identity-header middleware. The trust boundary is the IAM JWT: tasksd validates every Authorization: Bearer <jwt> against JWKS, writes X-Org-Id / X-User-Id / X-User-Email from validated claims, and unconditionally strips any client-supplied identity headers. There is no header-pass-through trust path; client-supplied identity headers are never honored.
In dev / embedded use, set TASKSD_REQUIRE_IDENTITY=false (the default) — requests without a token pass through with empty identity context. In production, set TASKSD_REQUIRE_IDENTITY=true so unauthenticated requests get 401.
Index ¶
- Constants
- func NewValidator(cfg JWTConfig) *edge.Verifier
- func OrgID(ctx context.Context) string
- func ProjectID(ctx context.Context) string
- func RequireIdentity(v *edge.Verifier, require bool) func(http.Handler) http.Handler
- func UserEmail(ctx context.Context) string
- func UserID(ctx context.Context) string
- func WithIdentity(ctx context.Context, org, project, user, email string) context.Context
- type JWTConfig
Constants ¶
const ( HeaderOrgID = authz.HeaderOrg HeaderProjectID = authz.HeaderProject HeaderUserID = authz.HeaderUser HeaderUserEmail = authz.HeaderUserEmail HeaderAuthorization = "Authorization" )
The identity header names are the ESTATE's, not this service's: one list, named by the party that writes their values (hanzoai/authz), so tasksd cannot come to disagree with the edge about what X-Org-Id means.
Variables ¶
This section is empty.
Functions ¶
func NewValidator ¶
NewValidator returns nil when cfg names no JWKS URL (JWT disabled).
The audience is optional here and that is deliberate, not an oversight: IAM sets `aud` per RFC 8707 to the requesting CLIENT, so it names who asked for the token rather than who may accept it. tasksd is not a client id, so it pins the issuer and the signing keys and lets any first-party client's token through.
func ProjectID ¶ added in v1.51.0
ProjectID returns the project id resolved from a validated JWT, or "" — the org/project/user identity model's middle scope. Convention: a project maps onto a tasks NAMESPACE inside the org's shard.
func RequireIdentity ¶
RequireIdentity returns middleware that:
- Strips any client-supplied X-Org-Id / X-User-Id / X-User-Email.
- If a Bearer JWT is present, validates it via v and writes fresh identity headers + ctx values from the claims.
- If require=true and no validated identity emerged, returns 401.
When v is nil (JWT disabled, embedded/dev mode) and require=false, every request passes through with empty identity ctx — useful for tests and the in-process embedder. When v is nil and require=true, every request is rejected (closed-by-default).
func WithIdentity ¶ added in v1.46.0
WithIdentity returns a context carrying an ALREADY-VALIDATED identity, for a caller that terminates the IAM trust boundary itself and embeds the Tasks HTTP surface in-process — e.g. the unified hanzoai/cloud binary, where the gateway validates the JWT and writes X-Org-Id / X-User-Id (HIP-0026) before the request ever reaches this handler. It is the in-process twin of RequireIdentity's write step: the engine reads org/user/email via OrgID/UserID/UserEmail identically, whether the identity was validated by the JWT path here or by a trusted upstream. Passing empty strings yields the unscoped (dev) context, the same as the no-token path — an embedder MUST therefore gate on its own validated principal before calling this, never on a raw client header.
Types ¶
type JWTConfig ¶
type JWTConfig struct {
JWKSURL string // e.g. https://hanzo.id/v1/iam/.well-known/jwks
// Issuer is the primary trusted issuer, e.g. https://hanzo.id. It is widened by
// Issuers for a deployment that fronts more than one brand; an empty result
// refuses every token rather than silently disabling the check.
Issuer string
// Issuers are ADDITIONAL trusted issuers beyond Issuer — the white-label brands
// this tasksd accepts tokens from, each of which signs its own.
Issuers []string
Audience string // optional; "" → audience check skipped
TTL time.Duration // JWKS cache TTL; 0 → the edge's default
}
JWTConfig configures the validator. An empty JWKSURL disables JWT validation, and RequireIdentity then refuses every request when require is set.