oauth2

package
v1.18.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: Apache-2.0 Imports: 44 Imported by: 3

README

pkg/oauth2

This package implements identity's OIDC/OAuth2 protocol layer.

Intent

The package is the point where external identity proof is turned into UNI-internal token and session state.

Its main responsibilities are:

  • implement the authorization and token endpoints
  • drive federated login against configured upstream identity providers
  • issue UNI access tokens and refresh tokens
  • validate UNI-issued tokens and project them into internal authn context
  • expose userinfo/introspection-like behaviour for downstream consumers

Although the package name says oauth2, the responsibility is broader: it implements the OIDC/OAuth2 protocol boundary used by identity.

This implementation remains a supported first-party deployment option. It is particularly important for local development and lower-friction deployments that should not require complex or costly integration with another authentication service.

Design Direction

Where possible, the package prefers stateless and opaque protocol handling.

Rather than persisting large amounts of protocol state server-side, it protects and round-trips state using encrypted tokens:

  • login dialog state
  • upstream OIDC state
  • authorization codes

That design reduces shared mutable state and helps the implementation scale without turning every protocol step into a database-backed workflow.

Internal Token Model

The package does not simply forward upstream provider tokens through the platform. It normalizes external identity into UNI-issued tokens that downstream services can handle consistently.

The main token classes are:

  • federated user tokens
  • service account tokens
  • service-to-service tokens

pkg/jose is the cryptographic trust anchor underneath this layer. pkg/oauth2 defines how those tokens are used, validated, refreshed, and mapped into local session semantics.

Invariants

  • This package is the built-in OIDC/OAuth2 implementation for identity and remains a supported path.
  • The package should prefer stateless, opaque, encrypted protocol state where practical.
  • UNI access tokens and refresh tokens are locally issued and locally verified.
  • Authorization codes, login state, and related protocol artifacts are protected as JWE rather than trusted as plain client-supplied data.
  • Redirect URI validation, PKCE validation, and client authentication are part of the security boundary.
  • Federated user sessions are persisted per client in the user record.
  • The package intentionally keeps a single active session/token chain per client.
  • Refresh tokens are single-use.
  • Reissuing tokens for a client session invalidates the prior active token for that session.
  • This session model is intended to reduce replay risk and detect token reuse rather than allowing multiple independently active refresh-token chains for the same client.
  • Token verification is intentionally cached because full validation is expensive.
  • Token classes for federated users, service accounts, and services are intentionally distinct.
  • Admission is intentionally coupled to local system validity: users who are inactive or not meaningful participants in the local authorization model should not be allowed to proceed as if they had a valid local identity.

Relationship To RBAC

This package is intentionally somewhat coupled to RBAC.

The goal is not only to prove who a user is, but also to avoid admitting principals into the local system when they are inactive or effectively not allowed to do anything useful. That is stricter than a pure external-authentication boundary, but it reduces attack surface and keeps local actor state aligned with local authorization rules.

pkg/oauth2 therefore establishes identity and session context in a way that later RBAC resolution can consume directly.

Service Authentication Direction

Historically, client credentials tokens were used as the service-to-service authentication and authorization mechanism, bound to X.509 client certificates.

That model is now transitional:

  • it was workable, but operationally messy
  • it has been superseded by direct mTLS identity derived from the client certificate common name

The client_credentials path is therefore still part of the package, but it is not the preferred long-term service-to-service model.

Token Exchange

The token endpoint implements the RFC 8693 token-exchange grant for UNI passports.

In the current flow, a caller presents an access token as the subject_token and identity issues a short-lived signed passport JWT. The passport records the source identity, account type, organization context, optional project context, and requested audience/resource values. It does not embed an ACL. The exchange computes ACL only to authorize the requested organization/project scope; downstream services continue to resolve permissions through the normal remote authorizer path keyed off the passport-verified principal.

Token-endpoint refusals follow RFC 6749 §5.2:

  • malformed token-exchange requests (missing or unsupported subject_token fields) → 400 invalid_request
  • presented subject-token failures (expired, malformed, principal not active) → 401 access_denied
  • scope failures (valid subject token, principal not a member of the requested org/project) → 400 invalid_scope

The remote middleware maps invalid_scope to 403 forbidden at the API edge.

Passport exchange is intentionally handled by the existing /oauth2/v2/token endpoint rather than a separate route. Token-exchange parameters must be form-encoded in the POST body so credentials are not accepted from URL query strings.

This keeps room for alternate authentication frontends to complement this package rather than replace it: external authentication can happen outside identity, while identity remains the issuer of the internal token shape consumed by downstream UNI services.

Source-token types and multi-issuer dispatch

The subject_token presented to passport exchange may be either:

  • a UNI-issued access token (a JWE), validated through GetUserinfo against the local user database, or
  • an external access token (a JWS) from any bearer-trusted OAuth2 provider.

The single entry point for both paths is dispatchUserinfo, which is also shared by the direct-bearer surfaces described below.

Routing on the JOSE header. Dispatch routes on the JOSE header of the compact serialization rather than counting dots. UNI access tokens are JWEs: their header carries an enc content-encryption field. External access tokens are JWSs: their header carries alg but no enc. The segment count (3 for JWS, 5 for JWE) is cross-checked against the header type so a stray member cannot misroute a token. A bearer that is neither — for example after an upstream access-token format change — is rejected outright and counted by unikorn_identity_bearer_tokens_unroutable.

External-token dispatch. For a JWS, dispatchUserinfo calls peekIssuer to extract the iss claim from the payload without signature verification (the peek only selects which keyset to verify against; trust still requires JWKS-validated signature plus issuer and audience equality). The issuer is then passed to validatorForIssuer, which:

  1. Lists all OAuth2Provider resources in the identity operator namespace. Providers in organization namespaces are never trusted.
  2. Filters to those with a bearerTrust block (bearer trust is opt-in; federation configuration alone never confers bearer trust).
  3. Includes a synthetic auth0-legacy entry built from the deprecated --auth0-exchange-issuer / --auth0-exchange-audience flags when those are set, preserving backward compatibility.
  4. Performs an exact string match on the issuer URL — the iss as the IdP emits it, verbatim (OIDC §3.1.3.7); no normalization. Operators must set spec.issuer to the exact iss (for Auth0, including the trailing slash).
  5. Returns the per-provider *auth0.Validator (cached by provider name + spec fingerprint via an LRU cache) together with the BearerTrustSpec and provider name.

When validatorForIssuer returns a cache-not-ready error (informer not yet synced), the dispatcher returns 503 Service Unavailable — this is a transient warm-up condition, not a trust failure. When the provider List succeeds but no provider matches the issuer, the token is rejected with 401 Unauthorized.

externalUserinfo then validates the token (signature, iss, aud, temporal claims, email, optional authz-claim), looks up UNI organization membership by email, and builds the userinfo and source-claims pair. UNI membership is always authoritative; claimed orgIds from the external token are discarded.

The src_iss claim. The resulting dispatchResult carries both a Source (coarse provider audit label, e.g. the OAuth2Provider name) and a SrcIss (the issuer URL verbatim, or the PassportSourceUNI sentinel for UNI-local tokens). SrcIss is stamped on the minted passport as src_iss and is the security-load-bearing value used by RBAC's platform-administrator fast-path. The sentinel "uni" is deliberately not a valid URL so it cannot collide with a real issuer.

Per-provider claim contract

Each bearer-trusted provider has a BearerTrustSpec that governs claim validation:

  • audience (required): the value that must appear in the token's aud claim by membership.
  • skipEmailVerification (default false): when false, the https://unikorn-cloud.org/email_verified claim must be present and true. Set to true only for providers that do not emit the claim.
  • requireAuthzClaim (default false): when true, the https://unikorn-cloud.org/authz claim must be present with acctype == "user" and at least one orgId. Used as a defense-in-depth signal that the UNI post-login Action ran. The claimed orgIds are discarded regardless.
  • allowExternalIdentity (default false): when true, subjects with no UNI user record are accepted with an empty orgIds slice instead of being rejected.
  • signingAlgorithms (default [RS256]): permitted JWS algorithms. Only asymmetric algorithms are accepted; symmetric algorithms (e.g. HS256) and none are rejected at trust-list build time.

The full claim contract and operator invariants are specified in docs/multi-issuer-token-contract.md.

Bearer surfaces

External access tokens may be presented in three ways:

  1. As the subject_token to the RFC 8693 token-exchange endpoint (/oauth2/v2/token), which returns a signed passport.
  2. Directly as a bearer token to local-authorizer-protected endpoints (/api/v1/*), where the local authorizer dispatches them via GetUserinfoFromBearer.
  3. Directly as a bearer token — or as the access_token form parameter — to the OIDC-advertised userinfo endpoint (/oauth2/v2/userinfo, both GET and POST), which dispatches via the same GetUserinfoFromBearer and returns the resolved userinfo claims.

All three paths share dispatchUserinfo and produce the same validation outcome. The two direct-bearer surfaces report surface="bearer" on the unikorn_identity_bearer_tokens_unroutable metric; token exchange reports surface="exchange". Any unauthenticated caller can increment this counter with a garbage bearer, so alert on a sustained rise rather than isolated events and expect scanner noise. UNI access tokens resolve on the userinfo endpoint regardless of external-provider configuration, as they always have.

JWKS throttling

The per-provider validator throttles upstream JWKS fetches with a minimum refresh interval, enforced by an HTTP transport wrapped around the go-oidc key set's client. The library refetches JWKS whenever no cached key verifies a token's signature — on unknown kids and on forged signatures over known kids alike — and only deduplicates concurrent refetches, so a stream of invalid tokens could otherwise drive one JWKS request per token and exhaust the provider's rate limit. Tokens verified by cached keys never reach the transport; a token demanding a refetch inside the interval is rejected as invalid without contacting the provider. The interval is configurable via Options.JWKSMinRefreshInterval and defaults to 60s. Each fetch is also bounded by a client timeout: go-oidc runs the fetch detached from the per-request context and deduplicates concurrent fetches against it, so an unbounded hung fetch would otherwise wedge the key set permanently.

Each suppressed fetch increments the unikorn_identity_auth0_jwks_refreshes_throttled counter (the metric name is historical); a sustained rise is the refetch-storm attack signature and what to alert on. Both this counter and unikorn_identity_bearer_tokens_unroutable are only exported when the service runs with --otlp-endpoint set: core attaches the metrics reader only then, and the chart leaves the endpoint unset by default, so a default deployment records the metrics but exports nothing and the alerts cannot fire until that endpoint is configured.

Caveats

  • The package mixes protocol handling, provider integration, local session persistence, local user admission checks, and token issuance. It is not a narrow wrapper around an OAuth library.
  • The package reaches into higher-level local concepts such as user database lookups and RBAC-aware admission decisions, so it is intentionally not protocol-pure.
  • Service token support and passport token exchange are both transition-sensitive areas and should be read in the context of the broader authn/authz evolution, not as isolated features.
  • Federated access tokens are still effectively bearer-style UNI tokens rather than sender-constrained tokens, so replay resistance depends more on lifetime, rotation, and session invalidation than on proof-of-possession.
  • Refresh token rotation and single-use enforcement are in place, but this area should continue to be reviewed against current OAuth security guidance for stronger replay-compromise handling.
  • pkg/jose, which provides key rotation, JWKS publication, and token cryptography
  • pkg/userdb, which shields this package from the raw local User/OrganizationUser/ServiceAccount storage joins used to resolve local identity state
  • pkg/apis/unikorn/v1alpha1, which defines the persisted user, provider, client, and signing-key resources this package relies on
  • pkg/rbac, which consumes the identity and session context established here

TODO

  • Mark the silent reauthentication session cookie as Secure for normal deployments so it is never sent over a non-TLS transport path, while allowing an explicit insecure-cookie mode for local HTTP development if that workflow must remain supported.
  • Harden login input validation in provider inference paths such as email-to-organization mapping so malformed input fails closed without panic-prone parsing.

Documentation

Index

Constants

View Source
const (
	// PassportTTL is the lifetime of a passport token. Sized to cover the
	// worst-case operational lifetime of a request that uses it: three
	// downstream hops at 15s per-hop API timeout plus 15s grace for clock
	// skew and tail latency.
	PassportTTL = 60 * time.Second

	// PassportType distinguishes passport tokens from access tokens.
	PassportType = "passport"

	// PassportIssuer is the issuer claim value for passport tokens.
	PassportIssuer = "uni-identity"

	// PassportSourceUNI indicates the source token was a UNI access token.
	// It aliases constants.UNISentinel so all existing references continue to compile.
	PassportSourceUNI = constants.UNISentinel
)
View Source
const (
	SessionCookie = "unikorn-identity-session"
)

Variables

View Source
var (
	ErrUnsupportedProviderType = goerrors.New("unhandled provider type")
	ErrReference               = goerrors.New("resource reference error")
	ErrUserNotDomainMapped     = goerrors.New("user is not domain mapped to an organization")
	ErrSourceTokenExpired      = goerrors.New("source token has expired")
)
View Source
var (
	// ErrKeyFormat is raised when something is wrong with the
	// encryption keys.
	ErrKeyFormat = errors.New("key format error")

	// ErrTokenVerification is raised when token verification fails.
	ErrTokenVerification = errors.New("failed to verify token")
)
View Source
var (
	// ErrCacheNotReady is returned when the provider List fails (e.g. informer
	// not yet synced). Callers on the JWS dispatch path surface this as HTTP 503
	// Service Unavailable, signaling a transient warm-up condition.
	ErrCacheNotReady = errors.New("provider list unavailable")

	// ErrUnknownIssuer is returned when no trusted provider's issuer matches the
	// token's iss claim. This is an expected outcome (an untrusted or unrecognized
	// issuer), not a lookup failure — callers surface it as HTTP 401, distinct from
	// the transient/config errors handleValidatorError otherwise handles.
	ErrUnknownIssuer = errors.New("no trusted provider matches issuer")
)

Functions

func AccessTokenSubjectTokenType added in v1.17.0

func AccessTokenSubjectTokenType() string

func PassportIssuedTokenType added in v1.17.0

func PassportIssuedTokenType() string

Types

type ActorClaim added in v1.17.0

type ActorClaim struct {
	// Subject identifies the acting party.
	Subject string `json:"sub"`
	// Act nests the previous actor when a delegation chain is in play.
	Act *ActorClaim `json:"act,omitempty"`
}

ActorClaim is the RFC 8693 section 4.1 "act" claim. It identifies the acting party in a delegation chain and is omitted when no delegation has occurred. Non-identity claims (exp, nbf, aud) are not meaningful here per the RFC and are deliberately not included.

type Authenticator

type Authenticator struct {
	// contains filtered or unexported fields
}

Authenticator provides Keystone authentication functionality.

func New

func New(options *Options, namespace string, issuer common.IssuerValue, client client.Client, jwtIssuer *jose.JWTIssuer, userdb *userdb.UserDatabase, rbac *rbac.RBAC) (*Authenticator, error)

New returns a new authenticator with required fields populated. It constructs the authenticator with the validator cache and initializes metrics. Per-provider validators are built lazily by validatorForIssuer when a passport is validated. Deprecated --auth0-exchange-{issuer,audience} flags feed a synthetic auth0-legacy provider for backward compatibility; new deployments should use OAuth2Provider bearerTrust blocks instead.

func (*Authenticator) Authorization

func (a *Authenticator) Authorization(w http.ResponseWriter, r *http.Request)

Authorization redirects the client to the OIDC autorization endpoint to get an authorization code. Note that this function is responsible for either returning an authorization grant or error via a HTTP 302 redirect, or returning a HTML fragment for errors that cannot follow the provided redirect URI.

func (*Authenticator) Callback added in v0.2.52

func (a *Authenticator) Callback(w http.ResponseWriter, r *http.Request)

OIDCCallback is called by the authorization endpoint in order to return an authorization back to us. We then exchange the code for an ID token, and refresh token. Remember, as far as the client is concerned we're still doing the code grant, so return errors in the redirect query.

func (*Authenticator) ExchangePassport added in v1.17.0

func (a *Authenticator) ExchangePassport(ctx context.Context, options *openapi.TokenRequestOptions) (*openapi.Token, error)

ExchangePassport runs the RFC 8693 token-exchange flow against pre-parsed request options. It validates the source access token, resolves identity, authorises the requested org/project scope, and returns a signed passport in the access_token field. The ACL is fetched only to authorise the requested scope; it is not embedded in the passport — downstream services continue to fetch ACL via the existing remote authoriser path keyed off passport-verified identity.

This is the entry point for in-process callers that already hold typed TokenRequestOptions and don't need form parsing. The HTTP handler reaches it via TokenExchange.

func (*Authenticator) GetUserinfo added in v0.2.58

func (a *Authenticator) GetUserinfo(ctx context.Context, r *http.Request, token string) (*openapi.Userinfo, *Claims, error)

GetUserinfo does access token introspection.

func (*Authenticator) GetUserinfoFromBearer added in v1.17.4

func (a *Authenticator) GetUserinfoFromBearer(ctx context.Context, r *http.Request, token string) (*openapi.Userinfo, *Claims, string, error)

GetUserinfoFromBearer resolves an external or UNI bearer token presented directly — to the local authorizer (/api/v1/...) or to the OIDC userinfo endpoint (/oauth2/v2/userinfo) — without the token-exchange round-trip. It shares dispatchUserinfo with the exchange path and returns the src_iss alongside userinfo and claims.

func (*Authenticator) InvalidateToken added in v0.2.49

func (a *Authenticator) InvalidateToken(ctx context.Context, token string)

InvalidateToken immediately invalidates the token so it's unusable again. TODO: this only considers caching in the identity service, it's still usable.

func (*Authenticator) Issue added in v0.1.13

func (a *Authenticator) Issue(ctx context.Context, info *IssueInfo) (*Tokens, error)

Issue issues a new JWT access token.

func (*Authenticator) Login

func (a *Authenticator) Login(w http.ResponseWriter, r *http.Request)

Login handles the response from the user login prompt.

func (*Authenticator) Token

Token issues an OAuth2 access token from the provided authorization code.

func (*Authenticator) TokenAuthorizationCode added in v0.2.30

func (a *Authenticator) TokenAuthorizationCode(w http.ResponseWriter, r *http.Request) (*openapi.Token, error)

TokenAuthorizationCode issues a token based on whether the provided code is correct and the client code verifier (PKCS) matches.

func (*Authenticator) TokenClientCredentials added in v0.2.30

func (a *Authenticator) TokenClientCredentials(w http.ResponseWriter, r *http.Request) (*openapi.Token, error)

TokenClientCredentials issues a token if the client credentials are valid. We only support mTLS based authentication. TODO: delete me, services should use mTLS alone.

func (*Authenticator) TokenExchange added in v1.16.1

func (a *Authenticator) TokenExchange(_ http.ResponseWriter, r *http.Request) (*openapi.Token, error)

TokenExchange implements RFC 8693 OAuth 2.0 Token Exchange for UNI passports when invoked via the OAuth 2.0 token endpoint. It parses the form body and hands off to ExchangePassport; non-handler callers should use that directly.

func (*Authenticator) TokenRefreshToken added in v0.2.30

func (a *Authenticator) TokenRefreshToken(w http.ResponseWriter, r *http.Request) (*openapi.Token, error)

TokenRefreshToken issues a token if the provided refresh token is valid.

func (*Authenticator) Verify added in v0.1.14

func (a *Authenticator) Verify(ctx context.Context, info *VerifyInfo) (*Claims, error)

Verify checks the access token parses and validates.

type Claims

type Claims struct {
	jwt.Claims `json:",inline"`
	// Type is the type of access token this is.
	Type TokenType `json:"typ"`
	// Federated is set when the type is a federated user.
	Federated *FederatedClaims `json:"fed,omitempty"`
	// ServiceAccount is set when the type is a service account.
	ServiceAccount *ServiceAccountClaims `json:"sa,omitempty"`
	// Service is set when the type is a service.
	Service *ServiceClaims `json:"svc,omitempty"`
}

Claims is an application specific set of claims. TODO: this technically isn't conformant to oauth2 in that we don't specify the client_id claim, and there are probably others.

type Code

type Code struct {
	// ID is a unique identifier for the code.
	ID string `json:"id"`
	// OAuth2Provider is the name of the provider configuration in
	// use, this will reference the issuer and allow discovery.
	OAuth2Provider string `json:"oap"`
	// UserID is the user that issued the code.
	UserID string `json:"uid"`
	// ClientQuery stores the full client query string.
	ClientQuery string `json:"cq"`
	// IDToken is the full set of claims returned by the provider.
	IDToken *oidc.IDToken `json:"idt"`
	// Interactive declares whether this is an interactive login
	// or not (e.g. cookie based).
	Interactive bool `json:"int"`
}

Code is an authorization code to return to the client that can be exchanged for an access token. Much like how we client things in the oauth2 state during the OIDC exchange, to mitigate problems with horizonal scaling and sharing stuff, we do the same here.

type Error

type Error string
const (
	ErrorInvalidRequest           Error = "invalid_request"
	ErrorUnauthorizedClient       Error = "unauthorized_client"
	ErrorAccessDenied             Error = "access_denied"
	ErrorUnsupportedResponseType  Error = "unsupported_response_type"
	ErrorInvalidScope             Error = "invalid_scope"
	ErrorServerError              Error = "server_error"
	ErrorLoginRequired            Error = "login_required"
	ErrorRequestNotSupported      Error = "request_not_supported"
	ErrorRequestURINotSupported   Error = "request_uri_not_supported"
	ErrorInteractionRequired      Error = "interaction_required"
	ErrorRegistrationNotSupported Error = "registration_not_supported"
)

type FederatedClaims added in v0.2.59

type FederatedClaims struct {
	// Provider is the backend identity provider.
	Provider string `json:"idp"`
	// ClientID is the oauth2 client that the user is using.
	ClientID string `json:"cid"`
	// UserID is set when the token is issued to a user.
	// TODO: this should be the subject.
	UserID string `json:"uid"`
	// Scope is the set of scopes requested by the client, and is used to
	// populate the userinfo response.
	Scope Scope `json:"sco"`
}

type IssueInfo added in v0.2.4

type IssueInfo struct {
	// Issuer should be from the HTTP Host header, as requested by the client.
	Issuer string
	// Audience should be from the HTTP Host header, as only we can decipher the token.
	Audience string
	// Subject is the user, or service account ID, the token is valid for.  This is used
	// for RBAC.
	Subject string
	// Type is the type of access token this is.
	Type TokenType `json:"typ"`
	// Federated is set when the type is a federated user.
	Federated *FederatedClaims `json:"fed,omitempty"`
	// ServiceAccount is set when the type is a service account.
	ServiceAccount *ServiceAccountClaims `json:"sa,omitempty"`
	// Service is set when the type is a service.
	Service *ServiceClaims `json:"svc,omitempty"`
	// Duration is the token lifetime.  Please note this should only be used for
	// service account tokens that by definition need to be long lived.
	Duration *time.Duration
	// Interactive declares whether this is an interactive login
	// or not (e.g. cookie based).
	Interactive bool `json:"int"`
	// AuthorizationCodeID is required when doing code exchange and records the
	AuthorizationCodeID *string
}

IssueInfo controls how the access token is encoded.

type LoginStateClaims added in v0.2.52

type LoginStateClaims struct {
	Query string `json:"query"`
}

LoginStateClaims are used to encrypt information across the login dialog.

type Options

type Options struct {
	// AccessTokenDuration should be short to prevent long term use.
	AccessTokenDuration time.Duration

	// RefreshTokenDuration should be driven by the signing key rotation
	// period.
	RefreshTokenDuration time.Duration

	// TokenVerificationLeeway tells us how permissive we should or shouldn't
	// be of timing.
	TokenVerificationLeeway time.Duration

	// TokenLeewayDuration allows us to remove a period from the IdP access token
	// lifetime so we can "guarantee" ours will expire before theirs and force
	// a refresh before any errors can come from the IdP.
	TokenLeewayDuration time.Duration

	// TokenCacheSize is used to control the size of the LRU cache for token validation
	// checks.  This bounds the memory use to prevent DoS attacks.
	TokenCacheSize int

	// CodeCacheSize is used to set the number of authorization code in flight.
	CodeCacheSize int

	// ValidatorCacheSize controls how many per-provider auth0.Validator instances
	// are kept in the LRU cache. Each entry holds a built validator keyed by
	// provider name + spec fingerprint.
	ValidatorCacheSize int

	// Auth0ExchangeIssuer is the Auth0 tenant issuer accepted as a passport
	// exchange source token issuer.
	Auth0ExchangeIssuer string

	// Auth0ExchangeAudience is the Auth0 API audience accepted for passport
	// exchange source tokens.
	Auth0ExchangeAudience string
}

func (*Options) AddFlags added in v0.1.16

func (o *Options) AddFlags(f *pflag.FlagSet)

type PassportClaims added in v1.17.0

type PassportClaims struct {
	jwt.Claims `json:",inline"`

	// Type distinguishes passports from access tokens.
	Type string `json:"typ"`
	// Acctype is the account type: "user", "service", or "system".
	Acctype openapi.AuthClaimsAcctype `json:"acctype"`
	// Source identifies which IdP issued the original token.
	Source string `json:"source"`
	// Email is the user's email address, if available.
	Email string `json:"email,omitempty"`
	// OrgIDs is the list of organization IDs the subject is authorized for.
	//nolint:tagliatelle
	OrgIDs []string `json:"org_ids"`
	// OrgID is the current organization context from the exchange request.
	//nolint:tagliatelle
	OrgID string `json:"org_id,omitempty"`
	// ProjectID is the current project context from the exchange request.
	//nolint:tagliatelle
	ProjectID string `json:"project_id,omitempty"`
	// SrcIss is the issuer URL (verbatim, as the IdP emits it) that authenticated
	// the subject, or the PassportSourceUNI sentinel for UNI-local tokens. It is
	// the security-load-bearing issuer for the platform-admin match; Source
	// stays a coarse audit label.
	//nolint:tagliatelle
	SrcIss string `json:"src_iss"`
	// Actor expresses delegation per RFC 8693 section 4.1; omitted when the
	// passport's subject is itself the acting party.
	Actor *ActorClaim `json:"act,omitempty"`
}

PassportClaims defines the JWT claims for a passport token.

type RefreshTokenClaims added in v0.2.4

type RefreshTokenClaims struct {
	jwt.Claims `json:",inline"`
	// Federated is set when the type is a federated user.
	Federated *FederatedClaims `json:"fed,omitempty"`
}

RefreshTokenClaims is a basic set of JWT claims, plus a wrapper for the IdP's refresh token.

type Scope

type Scope []string

Scope defines a list of scopes.

func NewScope

func NewScope(s string) Scope

NewScope creates a new scopes object.

func (*Scope) MarshalJSON added in v0.1.2

func (l *Scope) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaller.

func (*Scope) UnmarshalJSON added in v0.1.2

func (l *Scope) UnmarshalJSON(value []byte) error

UnmarshalJSON implments json.Unmarshaller.

type ServiceAccountClaims added in v0.2.59

type ServiceAccountClaims struct {
	// OrganizationID is the identifier of the organization.
	OrganizationID string `json:"oid"`
}

type ServiceClaims added in v0.2.59

type ServiceClaims struct {
	//nolint: tagliatelle
	X509Thumbprint string `json:"x5t@S256,omitempty"`
}

type State

type State struct {
	// Nonce is the one time nonce used to create the token.
	Nonce string `json:"n"`
	// Code verifier is required to prove our identity when
	// exchanging the code with the token endpoint.
	CodeVerifier string `json:"cv"`
	// OAuth2Provider is the name of the provider configuration in
	// use, this will reference the issuer and allow discovery.
	OAuth2Provider string `json:"oap"`
	// ClientQuery stores the full client query string.
	ClientQuery string `json:"cq"`
}

State records state across the call to the authorization server. This must be encrypted with JWE.

type TokenType added in v0.2.59

type TokenType string
const (
	// TokenTypeFederated is used for federated tokens e.g. huamns.
	TokenTypeFederated TokenType = "fed"
	// TokenTypeServiceAccount is used for service accounts.
	TokenTypeServiceAccount TokenType = "sa"
	// TokenTypeService is used by services acting on behalf of users.
	// TODO: delete me, services should use mTLS alone.
	TokenTypeService TokenType = "svc"
)

type Tokens added in v0.2.4

type Tokens struct {
	Expiry                 time.Time
	AccessToken            string
	RefreshToken           *string
	LastAuthenticationTime time.Time
}

Tokens is the set of tokens and metadata returned by a token issue.

type VerifyInfo added in v0.2.4

type VerifyInfo struct {
	Issuer   string
	Audience string
	Token    string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL