Documentation
¶
Overview ¶
Package identity provides immutable callers, owned claims and context transport. Construction validates representation; producers authenticate, and application policy authorizes. The package performs no network or signature verification.
Index ¶
- Variables
- func NewContext(ctx context.Context, caller Caller) (context.Context, error)
- type Caller
- type Claim
- func (c Claim) Array() ([]Claim, bool)
- func (c Claim) Bool() (value, ok bool)
- func (c Claim) Float64() (float64, bool)
- func (c Claim) GoString() string
- func (c Claim) Kind() ClaimKind
- func (c Claim) NumberText() (string, bool)
- func (c Claim) Object() (Claims, bool)
- func (c Claim) Representation() Representation
- func (c Claim) String() string
- func (c Claim) Text() (string, bool)
- type ClaimKind
- type Claims
- type ClaimsLimitError
- type ClaimsOption
- type IAM
- type IAMOption
- type IAMPrincipalType
- type JWT
- func (j JWT) Audience() ([]string, bool)
- func (j JWT) Claims() Claims
- func (j JWT) ClientID() (string, bool)
- func (j JWT) CognitoGroups() ([]string, bool)
- func (j JWT) GoString() string
- func (j JWT) Issuer() string
- func (j JWT) Scopes() ([]string, bool)
- func (j JWT) String() string
- func (j JWT) Subject() (string, bool)
- func (j JWT) TokenUse() (string, bool)
- type JWTOption
- type Kind
- type Representation
- type Source
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidCaller indicates invalid caller facts, provenance or options. ErrInvalidCaller = errors.New("identity: invalid caller") // ErrConflict indicates an attempt to replace an established caller. ErrConflict = errors.New("identity: caller conflict") // ErrInvalidClaims indicates malformed JSON, unsupported typed values, invalid UTF-8, nonfinite numbers, or excessive container nesting. ErrInvalidClaims = errors.New("identity: invalid claims") // ErrClaimsLimit indicates exhaustion of the wire or weighted byte allowance. ErrClaimsLimit = errors.New("identity: claims budget exceeded") )
Functions ¶
func NewContext ¶
NewContext returns a derived context carrying caller, for retrieval with FromContext. Anonymous on an empty context is a no-op. Any attempted installation over a nonanonymous caller, including an identical caller or anonymous, returns ErrConflict and a nil context. A nil context returns ErrInvalidCaller. Unrelated values are preserved.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"github.com/asteroid-computing/go-lambda-edge/identity"
)
func main() {
// This validates a synthetic identifier;
// it does not authenticate it.
caller, err := identity.NewIAM("arn:aws:sts::123456789012:assumed-role/Worker/batch-1", identity.SourceCustomAssertion)
if err != nil {
panic(err)
}
ctx, err := identity.NewContext(context.Background(), caller)
if err != nil {
panic(err)
}
iam, _ := identity.FromContext(ctx).IAM()
fmt.Println(iam.PrincipalARN())
_, err = identity.NewContext(ctx, caller)
fmt.Println(errors.Is(err, identity.ErrConflict))
}
Output: arn:aws:sts::123456789012:assumed-role/Worker/batch-1 true
Types ¶
type Caller ¶
type Caller struct {
// contains filtered or unexported fields
}
Caller is an immutable identity snapshot with exactly one JWT or IAM view. Its zero value is anonymous. Constructors validate facts; they neither authenticate nor authorize. Copies may be shared concurrently. There is no identity equality contract or implicit JSON export. Diagnostics omit facts.
func FromContext ¶
FromContext returns the established caller or the anonymous zero value. Like ordinary context operations, it requires a nonnil context.
func NewIAM ¶
NewIAM validates and owns an exact root, user, assumed-role session or federated-user ARN. Bare role ARNs and policy patterns are not caller forms. Literal punctuation in a valid IAM user path is preserved without wildcard interpretation. Source must be gateway, custom assertion or verified IAM proof. Errors match ErrInvalidCaller and contain no supplied identifiers.
func NewJWT ¶
NewJWT validates normalized facts and retains immutable claims. It requires a nonempty issuer and a subject or client_id, without conflating those fields. Allowed sources are gateway, locally verified token and custom assertion. It does not verify signatures or expiry. Invalid inputs match ErrInvalidCaller; a dedicated-scope budget failure additionally matches ErrClaimsLimit.
Example ¶
package main
import (
"fmt"
"github.com/asteroid-computing/go-lambda-edge/identity"
)
func main() {
// Synthetic facts for this example.
// In an application, an authenticating producer must establish these facts before constructing the caller.
claims, err := identity.NewClaims(map[string]any{"iss": "https://issuer.example", "client_id": "batch-worker", "scope": "orders.read"})
if err != nil {
panic(err)
}
caller, err := identity.NewJWT(claims, identity.SourceCustomAssertion)
if err != nil {
panic(err)
}
jwt, _ := caller.JWT()
client, _ := jwt.ClientID()
_, hasSubject := jwt.Subject()
scopes, known := jwt.Scopes()
fmt.Println(client, hasSubject, scopes, known)
}
Output: batch-worker false [orders.read] true
func (Caller) IAM ¶
IAM reports whether the caller has an IAM identity and returns an immutable view.
func (Caller) JWT ¶
JWT reports whether the caller has a JWT identity and returns an immutable view.
func (Caller) Kind ¶
Kind returns the identity representation, or KindAnonymous for the zero value.
func (Caller) Source ¶
Source returns the attributed producer, or SourceNone for an anonymous caller.
type Claim ¶
type Claim struct {
// contains filtered or unexported fields
}
Claim is an immutable view of a value. The zero value has kind ClaimInvalid. Its representation describes the available input, not authentication strength.
func (Claim) Array ¶
Array reports whether the claim is an array and returns a new slice of views. Replacing elements cannot mutate the original claims.
func (Claim) Float64 ¶
Float64 explicitly converts a number to its nearest float64 representation. It reports false for nonnumbers or a conversion error; ordinary rounding is permitted. For supplied floating-point values it returns their stored value. Use NumberText and an exact parser when rounding is unacceptable.
func (Claim) NumberText ¶
NumberText reports whether an exact numeric representation is available. JSON and json.Number preserve their supplied literal; native integers use decimal text. Supplied float32/float64 and all strings return false, even for integral values. Exactness describes the supplied value, not lost upstream data.
func (Claim) Representation ¶
func (c Claim) Representation() Representation
Representation returns the immediate input representation.
type ClaimKind ¶
type ClaimKind uint8
ClaimKind describes a claim's available semantic type.
type Claims ¶
type Claims struct {
// contains filtered or unexported fields
}
Claims is an immutable object of named claims. Its zero value is empty. Views may share owned backing storage and may be read concurrently. Use Lookup and its checked accessors to inspect values; diagnostic formatting does not reveal claim names or contents. There is no implicit JSON export.
func NewClaims ¶
func NewClaims(values map[string]any, opts ...ClaimsOption) (Claims, error)
NewClaims validates and owns already decoded values without a JSON round trip. Supported recursive values are nil, bool, string, built-in integers except uintptr, finite float32/float64, json.Number, map[string]any, map[string]string, []any and []string. Other defined types, pointers, structs and byte slices are rejected without calling user methods. A nil map is an empty object; a typed nil nested map/slice retains its object/array kind. A nil interface is null. Inputs must not change during construction; afterward they may be mutated. Invalid input matches ErrInvalidClaims; byte exhaustion is a ClaimsLimitError.
func NewTextClaims ¶
func NewTextClaims(values map[string]string, opts ...ClaimsOption) (Claims, error)
NewTextClaims owns gateway text without parsing embedded JSON or numbers. All values retain RepresentationGatewayText. Nil means an empty object. Ownership, options and errors follow NewClaims.
Example ¶
package main
import (
"fmt"
"github.com/asteroid-computing/go-lambda-edge/identity"
)
func main() {
claims, err := identity.NewTextClaims(map[string]string{"cognito:groups": `["staff"]`})
if err != nil {
fmt.Println(err)
return
}
claim, present := claims.Lookup("cognito:groups")
_, array := claim.Array()
fmt.Println("present:", present, "array:", array)
}
Output: present: true array: false
func ParseClaims ¶
func ParseClaims(data jsontext.Value, opts ...ClaimsOption) (Claims, error)
ParseClaims validates exactly one JSON object and owns its semantic contents. It preserves numeric token text, but not whitespace, member order or string escape spelling. It rejects duplicate names, invalid UTF-8 and trailing values. Input bytes must not change during construction and are not retained afterward. Invalid input matches ErrInvalidClaims; byte exhaustion is a ClaimsLimitError. The representation is received JSON, not proof of original JWT fidelity.
Example ¶
package main
import (
"encoding/json/jsontext"
"fmt"
"github.com/asteroid-computing/go-lambda-edge/identity"
)
func main() {
claims, err := identity.ParseClaims(jsontext.Value(`{"tenant":"orders","sequence":9007199254740993}`))
if err != nil {
fmt.Println(err)
return
}
if claim, present := claims.Lookup("sequence"); present {
if number, exact := claim.NumberText(); exact {
fmt.Println(number)
}
}
}
Output: 9007199254740993
type ClaimsLimitError ¶
type ClaimsLimitError struct {
// contains filtered or unexported fields
}
ClaimsLimitError describes a claims byte allowance failure. Its diagnostics contain no claim names, values, or underlying parser errors. The zero value has an unspecified maximum of zero.
func (*ClaimsLimitError) Error ¶
func (e *ClaimsLimitError) Error() string
Error returns a sanitized description of the failure.
func (*ClaimsLimitError) Maximum ¶
func (e *ClaimsLimitError) Maximum() int64
Maximum returns the configured allowance in bytes, or zero for a nil error.
func (*ClaimsLimitError) Unwrap ¶
func (e *ClaimsLimitError) Unwrap() error
Unwrap returns ErrClaimsLimit.
type ClaimsOption ¶
type ClaimsOption func(*claimsConfig)
ClaimsOption configures claims construction. A nil option is invalid. Scalar settings apply in order, with the last assignment winning.
func WithClaimsBudget ¶
func WithClaimsBudget(bytes int) ClaimsOption
WithClaimsBudget sets the weighted resource allowance in bytes, defaulting to 256 KiB. Constructors reject a final setting outside 1..6 MiB. Each value costs 64 bytes plus object-name, string and exact-number text bytes. ParseClaims also limits the original JSON byte length to this maximum. The allowance is not an AWS quota or a heap cap. Nesting is limited separately to 64 containers, including the root, and cannot be disabled.
type IAM ¶
type IAM struct {
// contains filtered or unexported fields
}
IAM is an immutable view of an exact caller ARN and optional principal ID. Validation does not establish existence, credential possession or permission.
func (IAM) PrincipalARN ¶
PrincipalARN returns the complete ARN, including any path and session name.
func (IAM) PrincipalID ¶
PrincipalID reports whether an opaque nonempty principal ID was supplied.
func (IAM) PrincipalType ¶
func (i IAM) PrincipalType() IAMPrincipalType
PrincipalType returns the validated caller form.
type IAMOption ¶
type IAMOption func(*iamConfig) error
IAMOption supplies an additional caller fact. Nil and duplicate options fail.
func WithIAMAccountID ¶
WithIAMAccountID cross-checks an independently supplied caller account against the ARN. Do not pass API Gateway's API-owner requestContext.accountId here.
func WithIAMPrincipalID ¶
WithIAMPrincipalID preserves a nonempty UTF-8 principal identifier opaquely. It is not parsed into an identity or treated as evidence of authentication.
type IAMPrincipalType ¶
type IAMPrincipalType uint8
IAMPrincipalType describes the supported request-caller form, not an IAM resource-policy Principal expression.
const ( IAMPrincipalUnknown IAMPrincipalType = iota IAMPrincipalRoot IAMPrincipalUser IAMPrincipalAssumedRole IAMPrincipalFederatedUser )
Supported IAM principal forms preserve session identities.
func (IAMPrincipalType) String ¶
func (t IAMPrincipalType) String() string
String returns a stable lowercase name such as "assumed_role", or "IAMPrincipalType(n)" for an undeclared value.
type JWT ¶
type JWT struct {
// contains filtered or unexported fields
}
JWT is an immutable view of normalized JWT facts and their owned claims. It makes no assertions about token validity, flow, expiry or permissions. Its zero value contains no identity facts.
func (JWT) Audience ¶
Audience returns a copied sorted set and reports whether its meaning is known. Gateway string audiences remain available in Claims but are not split or parsed.
func (JWT) CognitoGroups ¶
CognitoGroups returns a copied sorted set of cognito:groups when interpretable. It does not promote arbitrary groups or roles claims into Cognito groups.
func (JWT) Scopes ¶
Scopes returns a copied sorted set, distinguishing known empty from unavailable.
type JWTOption ¶
type JWTOption func(*jwtConfig) error
JWTOption supplies a separate assertion. Nil or duplicate options are invalid.
func WithGatewayScopes ¶
WithGatewayScopes supplies API Gateway's dedicated scopes collection. It is valid only with SourceGatewayAssertion. Nil means unavailable; a nonnil empty slice means known empty. Interpretable claim scopes must agree as exact sets. The supplied collection consumes the claims' remaining weighted budget before copying, even when its values duplicate a claim. Do not mutate it during NewJWT.
type Kind ¶
type Kind uint8
Kind identifies the caller's mutually exclusive identity representation.
type Representation ¶
type Representation uint8
Representation describes the immediate input representation, not its original token encoding or whether an authenticating producer verified it.
const ( RepresentationUnknown Representation = iota RepresentationJSON RepresentationDecoded RepresentationGatewayText )
Claim representations retain the distinction between JSON, decoded values, and gateway text that may have lost its original JSON type.
func (Representation) String ¶
func (r Representation) String() string
String returns a stable lowercase name such as "gateway_text", or "Representation(n)" for an undeclared value.
type Source ¶
type Source uint8
Source records the producer's assertion, not cryptographic evidence. Trusted application code must authenticate inputs before attributing a source.