Documentation
¶
Index ¶
- Constants
- Variables
- func AccessLogMiddleware(skipPaths ...string) gin.HandlerFunc
- func AdminAuditMiddleware(requireJustification bool) gin.HandlerFunc
- func ApplyGRPCAuthenticatedRateLimits(ctx context.Context, limiter *RateLimiter, fullMethod string, stream bool) error
- func AuthMiddleware(resolver *TokenResolver) gin.HandlerFunc
- func AuthMiddlewareWithAuthFailureRateLimiter(resolver *TokenResolver, limiter *RateLimiter) gin.HandlerFunc
- func AuthMiddlewareWithRateLimiter(resolver *TokenResolver, limiter *RateLimiter) gin.HandlerFunc
- func AuthenticatedRateLimitMiddleware(limiter *RateLimiter) gin.HandlerFunc
- func CheckGRPCOIDCScope(ctx context.Context, permission Permission) error
- func EffectiveAdminRole(c *gin.Context) string
- func ErrorEnvelopeMiddleware() gin.HandlerFunc
- func GRPCIdentityRateLimitStreamInterceptor(limiter *RateLimiter) grpc.StreamServerInterceptor
- func GRPCIdentityRateLimitUnaryInterceptor(limiter *RateLimiter) grpc.UnaryServerInterceptor
- func GRPCRequestIDStreamInterceptor() grpc.StreamServerInterceptor
- func GRPCRequestIDUnaryInterceptor() grpc.UnaryServerInterceptor
- func GRPCSourceRateLimitStreamInterceptor(limiter *RateLimiter) grpc.StreamServerInterceptor
- func GRPCSourceRateLimitUnaryInterceptor(limiter *RateLimiter) grpc.UnaryServerInterceptor
- func GRPCStreamInterceptor(resolver *TokenResolver) grpc.StreamServerInterceptor
- func GRPCStreamInterceptorWithRateLimiter(resolver *TokenResolver, limiter *RateLimiter) grpc.StreamServerInterceptor
- func GRPCUnaryInterceptor(resolver *TokenResolver) grpc.UnaryServerInterceptor
- func GRPCUnaryInterceptorWithRateLimiter(resolver *TokenResolver, limiter *RateLimiter) grpc.UnaryServerInterceptor
- func GetClientID(c *gin.Context) string
- func GetUserID(c *gin.Context) string
- func HasRole(c *gin.Context, role string) bool
- func InitMetrics(constLabels prometheus.Labels)
- func IsAdmin(c *gin.Context) bool
- func MetricsMiddleware() gin.HandlerFunc
- func ParseMetricsLabels(s string) (prometheus.Labels, error)
- func RecordLegacyEncryptedFieldRead(version string, provider string, domain string)
- func RecordLegacyEncryptedStreamRead(version string, provider string)
- func RequestIDFromContext(ctx context.Context) string
- func RequestIDFromGin(c *gin.Context) string
- func RequestIDMiddleware() gin.HandlerFunc
- func RequireAdminRole() gin.HandlerFunc
- func RequireAuditorRole() gin.HandlerFunc
- func RequireOIDCScope(permission Permission) gin.HandlerFunc
- func RequireUser() gin.HandlerFunc
- func SourceRateLimitMiddleware(limiter *RateLimiter) gin.HandlerFunc
- func ValidateRateLimitConfig(cfg *config.Config) error
- func WithEmbeddedMCPContext(ctx context.Context) context.Context
- func WithRequestID(ctx context.Context, requested string) (context.Context, string)
- type CredentialKind
- type Identity
- type Permission
- type PermissionDescriptor
- type RateLimitClass
- type RateLimiter
- type RequestCredentials
- type TokenResolver
- type UserIDAsserter
- func (a *UserIDAsserter) ApplyGRPCContext(ctx context.Context) (context.Context, error)
- func (a *UserIDAsserter) Enabled() bool
- func (a *UserIDAsserter) GRPCStreamInterceptor() grpc.StreamServerInterceptor
- func (a *UserIDAsserter) GRPCUnaryInterceptor() grpc.UnaryServerInterceptor
- func (a *UserIDAsserter) HTTPMiddleware() gin.HandlerFunc
Constants ¶
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" )
const ( RoleAdmin = "admin" RoleAuditor = "auditor" RoleIndexer = "indexer" )
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" )
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" )
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 ¶
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 ¶
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 ¶
GetClientID returns the agent client ID from the gin context.
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 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
RecordLegacyEncryptedFieldRead records and rate-limited-warns on compatibility reads of legacy encrypted persisted fields.
func RecordLegacyEncryptedStreamRead ¶ added in v0.0.6
RecordLegacyEncryptedStreamRead records and rate-limited-warns on compatibility reads of legacy encrypted attachment streams.
func RequestIDFromContext ¶ added in v0.0.6
RequestIDFromContext returns the request ID carried by a context, if any.
func RequestIDFromGin ¶ added in v0.0.6
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
ValidateRateLimitConfig validates the operator-facing rate-limit flags.
func WithEmbeddedMCPContext ¶ added in v0.0.3
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.
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
GetIdentity returns the resolved identity from the gin context.
func IdentityFromContext ¶
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
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.