domain

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Feb 21, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package domain defines authentication and authorization domain models and business logic.

It provides client-based authentication with policy-based authorization. Clients authenticate using secrets and are authorized via capability-based policies that control access to resource paths.

Package domain defines authentication and authorization domain models. Implements capability-based access control with clients, tokens, policies, and audit logging.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrClientNotFound indicates a client with the specified ID was not found.
	ErrClientNotFound = errors.Wrap(errors.ErrNotFound, "client not found")

	// ErrTokenNotFound indicates a token with the specified ID was not found.
	ErrTokenNotFound = errors.Wrap(errors.ErrNotFound, "token not found")

	// ErrInvalidCredentials indicates the provided credentials are invalid.
	// This error is returned for both non-existent clients and incorrect secrets
	// to prevent user enumeration attacks.
	ErrInvalidCredentials = errors.Wrap(errors.ErrUnauthorized, "invalid credentials")

	// ErrClientInactive indicates the client exists but is not active.
	// Inactive clients cannot authenticate or issue tokens.
	ErrClientInactive = errors.Wrap(errors.ErrForbidden, "client is inactive")

	// ErrSignatureInvalid indicates the audit log HMAC signature verification failed.
	// This typically means the audit log data has been tampered with after creation.
	ErrSignatureInvalid = errors.Wrap(errors.ErrInvalidInput, "audit log signature is invalid")

	// ErrSignatureMissing indicates the audit log does not have a cryptographic signature.
	// This is expected for legacy logs created before signature implementation.
	ErrSignatureMissing = errors.Wrap(errors.ErrNotFound, "audit log signature is missing")

	// ErrKekNotFoundForLog indicates the KEK referenced by an audit log signature
	// was not found in the KEK chain. This should not occur if KEK retention policy
	// is properly enforced (ON DELETE RESTRICT constraint).
	ErrKekNotFoundForLog = errors.Wrap(
		errors.ErrNotFound,
		"kek not found for audit log signature verification",
	)
)

Authentication and authorization errors.

Functions

This section is empty.

Types

type AuditLog

type AuditLog struct {
	ID         uuid.UUID
	RequestID  uuid.UUID
	ClientID   uuid.UUID
	Capability Capability
	Path       string
	Metadata   map[string]any
	Signature  []byte     // HMAC-SHA256 signature (32 bytes) for tamper detection
	KekID      *uuid.UUID // KEK used for signing (NULL for legacy unsigned logs)
	IsSigned   bool       // True if signed, false for legacy logs
	CreatedAt  time.Time
}

AuditLog records authorization decisions for compliance and security monitoring. Captures client identity, requested resource path, required capability, and metadata. Used to track access patterns and investigate security incidents.

Cryptographic Integrity: All audit logs are signed with HMAC-SHA256 using KEK-derived signing keys to detect tampering (PCI DSS Requirement 10.2.2). The Signature field contains the 32-byte HMAC, KekID references the KEK used for signing, and IsSigned distinguishes signed logs from legacy unsigned logs created before the feature.

func (*AuditLog) HasValidSignature added in v0.9.0

func (a *AuditLog) HasValidSignature() bool

HasValidSignature checks if the audit log has complete signature data. Returns true only if the log is marked as signed, has a KEK ID, and contains a 32-byte HMAC signature.

func (*AuditLog) IsLegacy added in v0.9.0

func (a *AuditLog) IsLegacy() bool

IsLegacy returns true if this is an unsigned legacy audit log created before cryptographic integrity was implemented. Legacy logs have no signature, no KEK ID, and are marked as unsigned.

type Capability

type Capability string

Capability defines the types of operations that can be performed on resources. Capabilities are used in policy documents to control client authorization.

const (
	// ReadCapability allows reading resource data.
	ReadCapability Capability = "read"

	// WriteCapability allows creating or updating resource data.
	WriteCapability Capability = "write"

	// DeleteCapability allows removing resource data.
	DeleteCapability Capability = "delete"

	// EncryptCapability allows encrypting data using cryptographic keys.
	EncryptCapability Capability = "encrypt"

	// DecryptCapability allows decrypting data using cryptographic keys.
	DecryptCapability Capability = "decrypt"

	// RotateCapability allows rotating cryptographic keys.
	RotateCapability Capability = "rotate"
)

type Client

type Client struct {
	ID        uuid.UUID        // Unique identifier (UUIDv7)
	Secret    string           //nolint:gosec // hashed client secret (not plaintext)
	Name      string           // Human-readable client name
	IsActive  bool             // Whether the client can authenticate
	Policies  []PolicyDocument // Authorization policies for this client
	CreatedAt time.Time
}

Client represents an authentication client with associated authorization policies. Clients are used to authenticate API requests and enforce access control.

func (*Client) IsAllowed

func (c *Client) IsAllowed(path string, capability Capability) bool

IsAllowed checks if the client's policies permit the given capability on the specified path. Uses case-sensitive path matching with wildcard support. Returns true if any policy matches the path and includes the capability.

Wildcard patterns:

  • "*" matches everything (admin mode)
  • "secret/*" matches any path starting with "secret/" (trailing wildcard - greedy)
  • "/v1/keys/*/rotate" matches "/v1/keys/payment/rotate" (single-segment wildcard)
  • "/v1/*/keys/*/rotate" matches "/v1/transit/keys/payment/rotate" (multiple wildcards)

Path matching rules:

  • Exact match: "secret" matches only "secret"
  • Trailing wildcard: "secret/*" matches "secret/app", "secret/app/db", etc.
  • Mid-path wildcard: "/v1/keys/*/rotate" matches exactly 4 segments with 3rd being any value
  • Case-sensitive: "Secret" does NOT match "secret"

type CreateClientInput

type CreateClientInput struct {
	Name     string           // Human-readable name for identifying the client
	IsActive bool             // Whether the client can authenticate immediately after creation
	Policies []PolicyDocument // Authorization policies defining resource access permissions
}

CreateClientInput contains the parameters for creating a new authentication client. The client secret will be automatically generated and cannot be specified by the caller.

type CreateClientOutput

type CreateClientOutput struct {
	ID          uuid.UUID // Unique identifier for the created client (UUIDv7)
	PlainSecret string    // Plain text secret for authentication (transmit securely, never log)
}

CreateClientOutput contains the result of creating a new client. SECURITY: The PlainSecret is only returned once and must be securely transmitted to the client. It will never be retrievable again after this response.

type IssueTokenInput

type IssueTokenInput struct {
	ClientID     uuid.UUID
	ClientSecret string //nolint:gosec // authentication credential field
}

IssueTokenInput contains client credentials for token issuance requests. Used during authentication to verify client identity before generating tokens.

type IssueTokenOutput

type IssueTokenOutput struct {
	PlainToken string
	ExpiresAt  time.Time
}

IssueTokenOutput contains the newly issued authentication token and expiration. The PlainToken is only returned once and must be transmitted securely to the client.

type PolicyDocument

type PolicyDocument struct {
	Path         string       `json:"path"`         // Resource path pattern (supports "*" and "/*" wildcards)
	Capabilities []Capability `json:"capabilities"` // List of allowed operations on the resource
}

PolicyDocument defines access control rules for a specific resource path. Policies use prefix matching with wildcard support for flexible authorization.

type Token

type Token struct {
	ID        uuid.UUID  // Unique identifier (UUIDv7)
	TokenHash string     // SHA-256 hash of the token string
	ClientID  uuid.UUID  // ID of the client that owns this token
	ExpiresAt time.Time  // Token expiration timestamp
	RevokedAt *time.Time // Token revocation timestamp (nil if active)
	CreatedAt time.Time
}

Token represents an authentication token with expiration and revocation support. Tokens are stored as hashes and associated with a client for authentication.

type UpdateClientInput

type UpdateClientInput struct {
	Name     string           // Updated human-readable name
	IsActive bool             // Updated active status (false prevents authentication)
	Policies []PolicyDocument // Updated authorization policies
}

UpdateClientInput contains the mutable fields for updating an existing client. The client ID and secret cannot be modified through updates.

Jump to

Keyboard shortcuts

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