security

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ContextKeyUserID is the gin context key for the authenticated user ID.
	ContextKeyUserID = "userID"
	// ContextKeyClientID is the gin context key for the agent client ID.
	ContextKeyClientID = "clientID"
	// ContextKeyRoles is the gin context key for resolved caller roles.
	ContextKeyRoles = "roles"
	// ContextKeyIsAdmin is the gin context key for admin authorization.
	ContextKeyIsAdmin = "isAdmin"
	// ContextKeyIdentity is the gin context key for the resolved caller identity.
	ContextKeyIdentity = "identity"
)
View Source
const (
	RoleAdmin   = "admin"
	RoleAuditor = "auditor"
	RoleIndexer = "indexer"
)
View Source
const (
	// HeaderRequestID is the canonical HTTP/gRPC metadata key used for request correlation.
	HeaderRequestID = "X-Request-ID"
	// ContextKeyRequestID is the gin context key for the request ID.
	ContextKeyRequestID = "requestID"
)
View Source
const (
	// HeaderUserID is the REST header used by trusted clients to select the
	// effective user for a normal user-scoped operation.
	HeaderUserID = "X-User-ID"
	// GRPCMetadataUserID is the canonical gRPC metadata spelling.
	GRPCMetadataUserID = "x-user-id"
)
View Source
const EmbeddedMCPTransport = "embedded-mcp"

EmbeddedMCPTransport is the string value stored in the context by WithEmbeddedMCPContext. Exported only so internal/cmd/mcp can reference it as documentation; the actual trust gate is the unexported context key, not this string.

Variables

View Source
var (

	// StoreLatency can be used by store implementations to record operation latency.
	StoreLatency *prometheus.HistogramVec

	CacheHitsTotal   prometheus.Counter
	CacheMissesTotal prometheus.Counter

	// DBPoolOpenConnections tracks the number of currently open database connections.
	DBPoolOpenConnections prometheus.Gauge

	// DBPoolMaxConnections tracks the configured maximum database connections.
	DBPoolMaxConnections prometheus.Gauge

	// SSEConnectionsActive tracks the number of currently active SSE connections.
	SSEConnectionsActive prometheus.Gauge

	// EventBusPublishedTotal counts total events published to the event bus.
	EventBusPublishedTotal prometheus.Counter

	// EventBusDeliveredTotal counts total events delivered to SSE clients.
	EventBusDeliveredTotal prometheus.Counter

	// EventBusDroppedTotal counts total events dropped (slow consumers or publish failures).
	EventBusDroppedTotal prometheus.Counter

	// EventBusSubscriberEvictionsTotal counts total slow subscribers evicted.
	EventBusSubscriberEvictionsTotal prometheus.Counter

	// RateLimitRequestsTotal counts process-local rate-limit decisions by bounded class/outcome labels.
	RateLimitRequestsTotal *prometheus.CounterVec

	// UserIDAssertionsTotal counts bounded trusted-user assertion outcomes.
	UserIDAssertionsTotal *prometheus.CounterVec

	// EncryptionLegacyStreamReadsTotal counts legacy encrypted stream reads by MSEH version.
	EncryptionLegacyStreamReadsTotal *prometheus.CounterVec

	// EncryptionLegacyFieldReadsTotal counts legacy encrypted field reads by MSEH version and bounded domain.
	EncryptionLegacyFieldReadsTotal *prometheus.CounterVec

	// SecurityUnsafeConfig records explicit operator acknowledgements for unsafe settings.
	SecurityUnsafeConfig *prometheus.GaugeVec
)

Functions

func AccessLogMiddleware

func AccessLogMiddleware(skipPaths ...string) gin.HandlerFunc

AccessLogMiddleware logs each HTTP request with method, path, status, and duration. Paths listed in skipPaths are silently passed through without logging.

func AdminAuditMiddleware

func AdminAuditMiddleware(requireJustification bool) gin.HandlerFunc

AdminAuditMiddleware logs admin API calls with caller identity and target resource. When requireJustification is true, admin requests must include a justification via query param (?justification=...) or X-Justification header.

func ApplyGRPCAuthenticatedRateLimits added in v0.0.6

func ApplyGRPCAuthenticatedRateLimits(ctx context.Context, limiter *RateLimiter, fullMethod string, stream bool) error

ApplyGRPCAuthenticatedRateLimits applies identity and operation rate limits after a handler has resolved the effective identity.

func AuthMiddleware

func AuthMiddleware(resolver *TokenResolver) gin.HandlerFunc

AuthMiddleware returns a gin middleware that extracts user identity from the request headers using the provided TokenResolver. Allows X-API-Key-only requests (for admin service principals) when no Authorization header is present.

func AuthMiddlewareWithAuthFailureRateLimiter added in v0.0.6

func AuthMiddlewareWithAuthFailureRateLimiter(resolver *TokenResolver, limiter *RateLimiter) gin.HandlerFunc

AuthMiddlewareWithAuthFailureRateLimiter resolves credentials and rate-limits authentication failures, while deferring authenticated identity limits to AuthenticatedRateLimitMiddleware. Use this when request identity may still be changed by trusted user assertion middleware.

func AuthMiddlewareWithRateLimiter added in v0.0.6

func AuthMiddlewareWithRateLimiter(resolver *TokenResolver, limiter *RateLimiter) gin.HandlerFunc

func AuthenticatedRateLimitMiddleware added in v0.0.6

func AuthenticatedRateLimitMiddleware(limiter *RateLimiter) gin.HandlerFunc

AuthenticatedRateLimitMiddleware enforces identity, expensive-operation, and stream-open limits after authentication and any user assertion.

func CheckGRPCOIDCScope added in v0.0.3

func CheckGRPCOIDCScope(ctx context.Context, permission Permission) error

CheckGRPCOIDCScope applies the same resource/API OIDC scope gate for gRPC handlers.

func EffectiveAdminRole

func EffectiveAdminRole(c *gin.Context) string

EffectiveAdminRole returns the highest resolved admin role.

func ErrorEnvelopeMiddleware added in v0.0.6

func ErrorEnvelopeMiddleware() gin.HandlerFunc

ErrorEnvelopeMiddleware normalizes non-streaming REST error responses that reach application middleware. Transport-level errors that happen before gin are outside this path.

func GRPCIdentityRateLimitStreamInterceptor added in v0.0.6

func GRPCIdentityRateLimitStreamInterceptor(limiter *RateLimiter) grpc.StreamServerInterceptor

GRPCIdentityRateLimitStreamInterceptor enforces identity and stream-open limits after stream auth resolution.

func GRPCIdentityRateLimitUnaryInterceptor added in v0.0.6

func GRPCIdentityRateLimitUnaryInterceptor(limiter *RateLimiter) grpc.UnaryServerInterceptor

GRPCIdentityRateLimitUnaryInterceptor enforces identity and expensive-operation limits after auth resolution.

func GRPCRequestIDStreamInterceptor added in v0.0.6

func GRPCRequestIDStreamInterceptor() grpc.StreamServerInterceptor

GRPCRequestIDStreamInterceptor attaches request ID metadata to streaming calls.

func GRPCRequestIDUnaryInterceptor added in v0.0.6

func GRPCRequestIDUnaryInterceptor() grpc.UnaryServerInterceptor

GRPCRequestIDUnaryInterceptor attaches request ID metadata to unary calls.

func GRPCSourceRateLimitStreamInterceptor added in v0.0.6

func GRPCSourceRateLimitStreamInterceptor(limiter *RateLimiter) grpc.StreamServerInterceptor

GRPCSourceRateLimitStreamInterceptor enforces source admission before stream auth resolution.

func GRPCSourceRateLimitUnaryInterceptor added in v0.0.6

func GRPCSourceRateLimitUnaryInterceptor(limiter *RateLimiter) grpc.UnaryServerInterceptor

GRPCSourceRateLimitUnaryInterceptor enforces source admission before auth resolution.

func GRPCStreamInterceptor

func GRPCStreamInterceptor(resolver *TokenResolver) grpc.StreamServerInterceptor

GRPCStreamInterceptor returns a gRPC stream server interceptor that resolves caller identity.

func GRPCStreamInterceptorWithRateLimiter added in v0.0.6

func GRPCStreamInterceptorWithRateLimiter(resolver *TokenResolver, limiter *RateLimiter) grpc.StreamServerInterceptor

GRPCStreamInterceptorWithRateLimiter returns a gRPC stream server interceptor that resolves caller identity and charges invalid credentials against the auth-failure bucket.

func GRPCUnaryInterceptor

func GRPCUnaryInterceptor(resolver *TokenResolver) grpc.UnaryServerInterceptor

GRPCUnaryInterceptor returns a gRPC unary server interceptor that resolves caller identity.

func GRPCUnaryInterceptorWithRateLimiter added in v0.0.6

func GRPCUnaryInterceptorWithRateLimiter(resolver *TokenResolver, limiter *RateLimiter) grpc.UnaryServerInterceptor

GRPCUnaryInterceptorWithRateLimiter returns a gRPC unary server interceptor that resolves caller identity and charges invalid credentials against the auth-failure bucket.

func GetClientID

func GetClientID(c *gin.Context) string

GetClientID returns the agent client ID from the gin context.

func GetUserID

func GetUserID(c *gin.Context) string

GetUserID returns the authenticated user ID from the gin context.

func HasRole

func HasRole(c *gin.Context, role string) bool

HasRole returns true if the caller has the given role.

func InitMetrics

func InitMetrics(constLabels prometheus.Labels)

InitMetrics registers all Prometheus metrics with the given constant labels. Must be called before starting the HTTP server or any store/cache initialization that records metrics. Safe to call multiple times; only the first call registers.

func IsAdmin

func IsAdmin(c *gin.Context) bool

IsAdmin returns true if the request is from an admin.

func MetricsMiddleware

func MetricsMiddleware() gin.HandlerFunc

MetricsMiddleware records HTTP request metrics for Prometheus.

func ParseMetricsLabels

func ParseMetricsLabels(s string) (prometheus.Labels, error)

ParseMetricsLabels parses a comma-separated list of key=value pairs into Prometheus labels. Values support ${VAR} / $VAR environment variable expansion. Label values may not contain commas. Returns nil for an empty string.

func RecordLegacyEncryptedFieldRead added in v0.0.6

func RecordLegacyEncryptedFieldRead(version string, provider string, domain string)

RecordLegacyEncryptedFieldRead records and rate-limited-warns on compatibility reads of legacy encrypted persisted fields.

func RecordLegacyEncryptedStreamRead added in v0.0.6

func RecordLegacyEncryptedStreamRead(version string, provider string)

RecordLegacyEncryptedStreamRead records and rate-limited-warns on compatibility reads of legacy encrypted attachment streams.

func RequestIDFromContext added in v0.0.6

func RequestIDFromContext(ctx context.Context) string

RequestIDFromContext returns the request ID carried by a context, if any.

func RequestIDFromGin added in v0.0.6

func RequestIDFromGin(c *gin.Context) string

RequestIDFromGin returns the request ID carried by a gin context, if any.

func RequestIDMiddleware added in v0.0.6

func RequestIDMiddleware() gin.HandlerFunc

RequestIDMiddleware attaches a safe request ID before recovery, auth, and route handlers.

func RequireAdminRole

func RequireAdminRole() gin.HandlerFunc

RequireAdminRole requires the caller to have admin role.

func RequireAuditorRole

func RequireAuditorRole() gin.HandlerFunc

RequireAuditorRole requires the caller to have auditor or admin role.

func RequireOIDCScope added in v0.0.3

func RequireOIDCScope(permission Permission) gin.HandlerFunc

RequireOIDCScope requires the configured OIDC scope for a resource/API permission. It is a no-op for non-OIDC identities and for permissions with no configured scopes.

func RequireUser added in v0.0.3

func RequireUser() gin.HandlerFunc

RequireUser requires a non-empty authenticated user principal. Client-only (API-key-only) identities are rejected with 401. This should be applied to all normal user/agent endpoints.

func SourceRateLimitMiddleware added in v0.0.6

func SourceRateLimitMiddleware(limiter *RateLimiter) gin.HandlerFunc

SourceRateLimitMiddleware enforces pre-auth source admission and auth-failure throttling.

func ValidateRateLimitConfig added in v0.0.6

func ValidateRateLimitConfig(cfg *config.Config) error

ValidateRateLimitConfig validates the operator-facing rate-limit flags.

func WithEmbeddedMCPContext added in v0.0.3

func WithEmbeddedMCPContext(ctx context.Context) context.Context

WithEmbeddedMCPContext stamps a request context as coming from the in-process embedded MCP transport. It must be called only by the in-process handlerTransport.RoundTrip. Remote callers cannot replicate this because embeddedMCPContextKey is unexported.

func WithRequestID added in v0.0.6

func WithRequestID(ctx context.Context, requested string) (context.Context, string)

WithRequestID returns a child context carrying a validated or generated request ID.

Types

type CredentialKind added in v0.0.3

type CredentialKind string

CredentialKind describes the accepted credential combination for an identity.

const (
	// CredentialOIDC — OIDC JWT bearer token only.
	CredentialOIDC CredentialKind = "oidc"
	// CredentialAPIKey — X-API-Key only (client-only service principal).
	CredentialAPIKey CredentialKind = "api-key"
	// CredentialOIDCAPIKey — OIDC JWT bearer token paired with X-API-Key.
	CredentialOIDCAPIKey CredentialKind = "oidc-api-key"
	// CredentialBearerAPIKey — bearer API key compatibility for no-OIDC deployments.
	CredentialBearerAPIKey CredentialKind = "bearer-api-key"
	// CredentialEmbeddedMCP — in-process embedded MCP synthetic identity.
	// Accepted only when RequestCredentials.Transport == "embedded-mcp"; never from network traffic.
	CredentialEmbeddedMCP     CredentialKind = "embedded-mcp"
	CredentialLocalUnixSocket CredentialKind = "local-unix-socket"
	// CredentialTesting — raw bearer user accepted only in testing mode with auth_testfixtures build tag.
	CredentialTesting CredentialKind = "testing-bearer-user"
)

type Identity

type Identity struct {
	// AuthenticatedUserID is the user resolved from the base credential. UserID
	// may differ when a trusted client asserts an effective user for a user API.
	AuthenticatedUserID string
	UserID              string
	ClientID            string
	UserRoles           map[string]bool
	ClientRoles         map[string]bool
	Roles               map[string]bool
	IsAdmin             bool
	UserIDAsserted      bool
	CredentialKind      CredentialKind
	HasOIDCToken        bool
	OIDCScopes          map[string]bool
	OIDCScopeGates      map[Permission]map[string]bool
}

Identity holds the resolved caller identity from a bearer token.

func GetIdentity added in v0.0.3

func GetIdentity(c *gin.Context) *Identity

GetIdentity returns the resolved identity from the gin context.

func IdentityFromContext

func IdentityFromContext(ctx context.Context) *Identity

IdentityFromContext retrieves the Identity stored in a context by the gRPC interceptor.

type Permission added in v0.0.3

type Permission string

Permission is a fixed Memory Service API capability that can be additionally gated by configured OIDC token scopes.

const (
	PermissionUser                    Permission = "user"
	PermissionUserRead                Permission = "user_read"
	PermissionUserWrite               Permission = "user_write"
	PermissionAdmin                   Permission = "admin"
	PermissionAdminRead               Permission = "admin_read"
	PermissionAdminWrite              Permission = "admin_write"
	PermissionSystemRead              Permission = "system_read"
	PermissionConversations           Permission = "conversations"
	PermissionConversationsRead       Permission = "conversations_read"
	PermissionConversationsWrite      Permission = "conversations_write"
	PermissionSharing                 Permission = "sharing"
	PermissionSharingRead             Permission = "sharing_read"
	PermissionSharingWrite            Permission = "sharing_write"
	PermissionSearch                  Permission = "search"
	PermissionSearchRead              Permission = "search_read"
	PermissionSearchWrite             Permission = "search_write"
	PermissionMemories                Permission = "memories"
	PermissionMemoriesRead            Permission = "memories_read"
	PermissionMemoriesWrite           Permission = "memories_write"
	PermissionAttachments             Permission = "attachments"
	PermissionAttachmentsRead         Permission = "attachments_read"
	PermissionAttachmentsWrite        Permission = "attachments_write"
	PermissionEventsRead              Permission = "events_read"
	PermissionRecordings              Permission = "recordings"
	PermissionRecordingsRead          Permission = "recordings_read"
	PermissionRecordingsWrite         Permission = "recordings_write"
	PermissionAdminConversations      Permission = "admin_conversations"
	PermissionAdminConversationsRead  Permission = "admin_conversations_read"
	PermissionAdminConversationsWrite Permission = "admin_conversations_write"
	PermissionAdminMemories           Permission = "admin_memories"
	PermissionAdminMemoriesRead       Permission = "admin_memories_read"
	PermissionAdminMemoriesWrite      Permission = "admin_memories_write"
	PermissionAdminAttachments        Permission = "admin_attachments"
	PermissionAdminAttachmentsRead    Permission = "admin_attachments_read"
	PermissionAdminAttachmentsWrite   Permission = "admin_attachments_write"
	PermissionAdminEventsRead         Permission = "admin_events_read"
	PermissionAdminCheckpoints        Permission = "admin_checkpoints"
	PermissionAdminCheckpointsRead    Permission = "admin_checkpoints_read"
	PermissionAdminCheckpointsWrite   Permission = "admin_checkpoints_write"
	PermissionAdminStatsRead          Permission = "admin_stats_read"
	PermissionAdminMaintenanceWrite   Permission = "admin_maintenance_write"
)

type PermissionDescriptor added in v0.0.3

type PermissionDescriptor struct {
	Permission Permission
	FlagName   string
	EnvVar     string
	Usage      string
}

PermissionDescriptor describes the explicit flag/env mapping for one fixed permission key.

func PermissionDescriptors added in v0.0.3

func PermissionDescriptors() []PermissionDescriptor

PermissionDescriptors returns the fixed OIDC scope permission vocabulary.

type RateLimitClass added in v0.0.6

type RateLimitClass string

RateLimitClass is the bounded metric label and bucket namespace for one limiter class.

const (
	RateLimitSource      RateLimitClass = "source"
	RateLimitIdentity    RateLimitClass = "identity"
	RateLimitAuthFailure RateLimitClass = "auth_failure"
	RateLimitExpensive   RateLimitClass = "expensive"
	RateLimitStreamOpen  RateLimitClass = "stream_open"
)

type RateLimiter added in v0.0.6

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

RateLimiter enforces process-local token buckets for main-listener HTTP and gRPC traffic.

func NewRateLimiter added in v0.0.6

func NewRateLimiter(cfg *config.Config) (*RateLimiter, error)

NewRateLimiter builds a process-local limiter from config. It returns a disabled limiter when mode=off.

type RequestCredentials added in v0.0.3

type RequestCredentials struct {
	// BearerToken is the value after stripping "Bearer " from Authorization header.
	BearerToken string
	// APIKey is the X-API-Key header value.
	APIKey string
	// ClientIDHeader is the X-Client-ID header value (testing/dev compatibility only).
	ClientIDHeader string
	// Transport, when set to EmbeddedMCPTransport, causes the resolver to produce a
	// CredentialEmbeddedMCP identity using the resolver's embedded user/client config.
	// Set only by AuthMiddleware after reading isEmbeddedMCPRequest; never from headers.
	Transport string
}

RequestCredentials is the transport-neutral credential shape extracted from HTTP or gRPC.

type TokenResolver

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

TokenResolver resolves bearer tokens to caller identities. It is initialized once at startup and shared by both the HTTP middleware and gRPC interceptors.

func NewTokenResolver

func NewTokenResolver(cfg *config.Config) (*TokenResolver, error)

NewTokenResolver creates a TokenResolver from the application config. It performs one-time OIDC provider discovery if OIDCIssuer is configured. Returns an error if OIDC is configured but discovery fails.

func (*TokenResolver) ConfigureEmbeddedMCP added in v0.0.3

func (r *TokenResolver) ConfigureEmbeddedMCP(userID, clientID string)

ConfigureEmbeddedMCP sets the synthetic user and client identity used by the in-process embedded MCP transport. Call this after NewTokenResolver when building an embedded MCP server. The resolver will return CredentialEmbeddedMCP for requests carrying Transport == EmbeddedMCPTransport.

func (*TokenResolver) Resolve

func (r *TokenResolver) Resolve(ctx context.Context, creds RequestCredentials) (*Identity, error)

Resolve resolves a RequestCredentials into a caller Identity. It applies all configured credential policies based on the deployment configuration.

type UserIDAsserter added in v0.0.6

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

UserIDAsserter applies user identity metadata only for exact trusted client IDs.

func NewUserIDAsserter added in v0.0.6

func NewUserIDAsserter(configured string) *UserIDAsserter

NewUserIDAsserter parses a comma-separated exact client allowlist.

func (*UserIDAsserter) ApplyGRPCContext added in v0.0.6

func (a *UserIDAsserter) ApplyGRPCContext(ctx context.Context) (context.Context, error)

ApplyGRPCContext applies x-user-id to an already authenticated gRPC context. It is also used inside mixed-scope streaming handlers after their request scope is known.

func (*UserIDAsserter) Enabled added in v0.0.6

func (a *UserIDAsserter) Enabled() bool

Enabled reports whether at least one client is trusted to assert users.

func (*UserIDAsserter) GRPCStreamInterceptor added in v0.0.6

func (a *UserIDAsserter) GRPCStreamInterceptor() grpc.StreamServerInterceptor

GRPCStreamInterceptor applies assertions to normal user-scoped streams. EventStreamService is handled after SubscribeEventsRequest.scope is known and is deliberately excluded here.

func (*UserIDAsserter) GRPCUnaryInterceptor added in v0.0.6

func (a *UserIDAsserter) GRPCUnaryInterceptor() grpc.UnaryServerInterceptor

GRPCUnaryInterceptor applies assertions only to normal user-scoped methods.

func (*UserIDAsserter) HTTPMiddleware added in v0.0.6

func (a *UserIDAsserter) HTTPMiddleware() gin.HandlerFunc

HTTPMiddleware applies X-User-ID after base authentication on normal user routes.

Jump to

Keyboard shortcuts

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