Documentation
¶
Index ¶
- Constants
- func AgentIDFromContext(ctx interface{ ... }) uuid.UUID
- func AgentMiddleware(jwtSecret string) func(http.Handler) http.Handler
- func AudienceContains(aud jwt.ClaimStrings, target string) bool
- func CheckPassword(hash, password string) error
- func HashPassword(password string) (string, error)
- func IssueAgentToken(secret string, agentID uuid.UUID) (string, error)
- func IssueOAuthAccessToken(secret string, userID uuid.UUID, ...) (string, error)
- func IssueRefreshToken(secret string, userID uuid.UUID, email, tenantRole string) (string, error)
- func IssueToken(secret string, userID uuid.UUID, email, tenantRole string) (string, error)
- func IssueTokenWithDuration(secret string, userID uuid.UUID, email, tenantRole string, ...) (string, error)
- func Middleware(jwtSecret string) func(http.Handler) http.Handler
- func RequireTenantRole(minRole Role) func(http.Handler) http.Handler
- func ScopeContains(scope, required string) bool
- func UserIDFromContext(ctx context.Context) uuid.UUID
- type AgentClaims
- type Claims
- type Role
Constants ¶
const ( AccessTokenDuration = 15 * time.Minute RefreshTokenDuration = 7 * 24 * time.Hour )
Variables ¶
This section is empty.
Functions ¶
func AgentIDFromContext ¶
AgentIDFromContext returns the agent UUID from context, set by AgentMiddleware.
func AgentMiddleware ¶
AgentMiddleware validates the agent JWT Bearer token and injects AgentClaims into context.
func AudienceContains ¶
func AudienceContains(aud jwt.ClaimStrings, target string) bool
AudienceContains reports whether `target` is one of the audience values in the claim. Helper for the MCP endpoint's audience check.
func CheckPassword ¶
CheckPassword compares a plaintext password with a bcrypt hash. Returns nil on success, error on mismatch.
func HashPassword ¶
HashPassword hashes a plaintext password using bcrypt.
func IssueAgentToken ¶
IssueAgentToken creates a signed JWT for an agent container (100-year expiry).
func IssueOAuthAccessToken ¶ added in v0.4.0
func IssueOAuthAccessToken(secret string, userID uuid.UUID, email, tenantRole, clientID, scope, audience string) (string, error)
IssueOAuthAccessToken mints a JWT with the OAuth-side claims set (ClientID + Scope + Audience). 15-min lifetime, same HS256 secret as the web-login tokens.
This is the SOLE call site in the codebase that sets ClientID. Anything else producing a JWT must not — the MCP endpoint uses ClientID's presence to decide whether the audience check should run. The web-login IssueToken / IssueTokenWithDuration paths deliberately keep ClientID empty.
audience is the canonical resource URL, e.g. "https://airlock.example.com/api/agent/<uuid>/mcp". scope is the space-delimited scope string ("mcp" in v1).
func IssueRefreshToken ¶
IssueRefreshToken creates a signed refresh token (7 days).
func IssueToken ¶
IssueToken creates a signed access token (15 min).
func IssueTokenWithDuration ¶
func IssueTokenWithDuration(secret string, userID uuid.UUID, email, tenantRole string, duration time.Duration) (string, error)
IssueTokenWithDuration creates a signed token with a custom duration.
func Middleware ¶
Middleware validates the JWT Bearer token and injects claims into context. It returns 401 for missing, invalid, or expired tokens.
func RequireTenantRole ¶
RequireTenantRole returns middleware that checks the user has at least the given role. Uses hierarchy: admin > manager > user. Returns 403 if not authorized.
func ScopeContains ¶ added in v0.4.0
ScopeContains reports whether `required` is present in a space-delimited scope string. OAuth 2.0 scopes are case-sensitive (RFC 6749 §3.3); we match exactly.
Types ¶
type AgentClaims ¶
type AgentClaims struct {
jwt.RegisteredClaims
AgentID string `json:"agent_id"`
}
AgentClaims are the JWT claims for agent tokens.
func ValidateAgentToken ¶
func ValidateAgentToken(secret, tokenString string) (*AgentClaims, error)
ValidateAgentToken validates a JWT and returns the agent claims. Rejects tokens that do not have an AgentID claim.
type Claims ¶
type Claims struct {
jwt.RegisteredClaims
Email string `json:"email"`
TenantRole string `json:"tenant_role"`
ClientID string `json:"client_id,omitempty"`
Scope string `json:"scope,omitempty"`
}
Claims are the JWT claims for Airlock tokens.
ClientID and Scope are populated ONLY by IssueOAuthAccessToken (the MCP server-side OAuth flow). Web-login tokens never carry them — the presence of ClientID is the discriminator the MCP endpoint uses to branch between "OAuth access token, verify aud+scope+client" and "web-login JWT, accept as-is". Anything else in this codebase that sets ClientID would break that discrimination — see the Test_UserJWTHasNoClientID invariant in jwt_test.go.
Audience comes from jwt.RegisteredClaims and binds an OAuth access token to a specific agent's MCP URL (RFC 8707 resource indicators).
func ClaimsFromContext ¶
ClaimsFromContext retrieves the JWT claims from the context.
func ValidateToken ¶
ValidateToken validates a JWT and returns the claims.