pub struct SecurityContext {Show 13 fields
pub user_id: UserId,
pub roles: Vec<String>,
pub tenant_id: Option<TenantId>,
pub scopes: Vec<String>,
pub attributes: HashMap<String, Value>,
pub request_id: String,
pub ip_address: Option<String>,
pub authenticated_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
pub issuer: Option<String>,
pub audience: Option<String>,
pub email: Option<String>,
pub display_name: Option<String>,
}Expand description
Security context for authorization evaluation.
Carries information about the authenticated user and their permissions throughout the request lifecycle.
§Fields
user_id: Unique identifier for the authenticated user (from JWT ‘sub’ claim)roles: User’s roles (e.g.,["admin", "moderator"], from JWT ‘roles’ claim)tenant_id: Organization/tenant identifier for multi-tenant systemsscopes: OAuth/permission scopes (e.g.,["read:user", "write:post"])attributes: Custom claims from JWT (e.g., department, region, tier)request_id: Correlation ID for audit logging and tracingip_address: Client IP address for geolocation and fraud detectionauthenticated_at: When the JWT was issuedexpires_at: When the JWT expiresissuer: Token issuer for multi-issuer systemsaudience: Token audience for validation
Fields§
§user_id: UserIdUser ID (from JWT ‘sub’ claim)
roles: Vec<String>User’s roles (e.g., ["admin", "moderator"])
Extracted from JWT ‘roles’ claim or derived from other claims. Used for role-based access control (RBAC) decisions.
tenant_id: Option<TenantId>Tenant/organization ID (for multi-tenancy)
When present, RLS policies can enforce tenant isolation.
Extracted from JWT ‘tenant_id’ or X-Tenant-Id header.
scopes: Vec<String>OAuth/permission scopes
Format: {action}:{resource} or {action}:{type}.{field}
Examples:
read:userwrite:postread:User.emailadmin:*
Extracted from JWT ‘scope’ claim.
attributes: HashMap<String, Value>Custom attributes from JWT claims
Arbitrary key-value pairs from JWT payload. Examples: “department”, “region”, “tier”, “country”
Used by custom RLS policies that need domain-specific attributes.
request_id: StringRequest correlation ID for audit trails
Extracted from X-Request-Id header or generated. Used for tracing and audit logging across services.
ip_address: Option<String>Client IP address
Extracted from X-Forwarded-For or connection socket. Used for geolocation and fraud detection in RLS policies.
authenticated_at: DateTime<Utc>When the JWT was issued
expires_at: DateTime<Utc>When the JWT expires
issuer: Option<String>Token issuer (for multi-issuer systems)
audience: Option<String>Token audience (for audience validation)
email: Option<String>Normalised email address from the JWT email claim.
Available as jwt:email in session variable mappings for RLS policies.
display_name: Option<String>Normalised display name from the JWT name claim.
Available as jwt:name or jwt:display_name in session variable mappings.
Implementations§
Source§impl SecurityContext
impl SecurityContext
Sourcepub const ACTING_FOR_ATTRIBUTE: &'static str = "fraiseql.acting_for"
pub const ACTING_FOR_ATTRIBUTE: &'static str = "fraiseql.acting_for"
Attribute key under which the delegated user’s UUID is carried (string
form), for an agent request acting on behalf of a human. Read back via
acting_for (#390).
Sourcepub const ACTOR_TYPE_ATTRIBUTE: &'static str = "fraiseql.actor_type"
pub const ACTOR_TYPE_ATTRIBUTE: &'static str = "fraiseql.actor_type"
Attribute key under which the request’s ActorType is carried (the
snake_case token), derived at from_user and read
back via actor_type (#390).
Sourcepub const TRACE_CONTEXT_ATTRIBUTE: &'static str = "fraiseql.trace_context"
pub const TRACE_CONTEXT_ATTRIBUTE: &'static str = "fraiseql.trace_context"
Attribute key under which the originating request’s full W3C trace context
is carried (a JSON object), used to populate the change-log trace_context
JSONB column (#375).
Sourcepub const TRACE_ID_ATTRIBUTE: &'static str = "fraiseql.trace_id"
pub const TRACE_ID_ATTRIBUTE: &'static str = "fraiseql.trace_id"
Attribute key under which the originating request’s W3C trace id is
stamped. Set by the server’s request pipeline from the inbound
traceparent header; read back via trace_id.
Sourcepub fn from_user(user: &AuthenticatedUser, request_id: String) -> Self
pub fn from_user(user: &AuthenticatedUser, request_id: String) -> Self
Create a security context from an authenticated user and request metadata.
§Arguments
user- Authenticated user from JWT validationrequest_id- Correlation ID for this request
§Example
// Requires: a live AuthenticatedUser from JWT validation.
// See: tests/integration/ for runnable examples.
let context = SecurityContext::from_user(&authenticated_user, "req-123".to_string());Sourcepub fn system_job(
job_id: impl Into<String>,
request_id: impl Into<String>,
roles: Vec<String>,
scopes: Vec<String>,
tenant: Option<TenantId>,
) -> Self
pub fn system_job( job_id: impl Into<String>, request_id: impl Into<String>, roles: Vec<String>, scopes: Vec<String>, tenant: Option<TenantId>, ) -> Self
Construct the context for an internal scheduled / system job (#573 D6).
Unlike from_user, this carries no JWT and no request
— it is the server acting as itself for background work: a scheduled
Source, and (in future) after:ingest
handlers and saga steps. It is the first and, at introduction, only
construction of ActorType::SystemJob.
Its authority is exactly the roles + scopes the caller grants (the
source’s run_as ceiling). With neither, it is fail-closed: no roles and
no scopes mean every RBAC / field-authz check denies and — with no tenant —
tenant-scoped RLS admits nothing. A source therefore cannot write until an
operator grants it a ceiling.
tenant scopes writes for a single-tenant or global source (None = global
/ NULL tenant); a multi-tenant source leaves it None and re-scopes each
write per message via with_tenant. job_id names the
job (the source name) and becomes the system_job:<id> principal for the
audit envelope; request_id correlates a single firing.
The ActorType is recorded for audit, never an authorization input — the
authority comes solely from roles/scopes.
Sourcepub fn get_attribute(&self, key: &str) -> Option<&Value>
pub fn get_attribute(&self, key: &str) -> Option<&Value>
Sourcepub fn trace_id(&self) -> Option<&str>
pub fn trace_id(&self) -> Option<&str>
The originating request’s W3C trace id, when the server stamped one from
the inbound traceparent header.
Used to populate the change-log trace_id column so an outbox row links
back to its distributed trace (#375); the #392 perf tooling surfaces it as
the investigation handle. None when the request carried no trace context.
Sourcepub fn with_trace_id(self, trace_id: impl Into<String>) -> Self
pub fn with_trace_id(self, trace_id: impl Into<String>) -> Self
Stamp the originating request’s W3C trace id onto the context (carried in
attributes). Read back via trace_id.
Sourcepub fn trace_context(&self) -> Option<&Value>
pub fn trace_context(&self) -> Option<&Value>
The originating request’s full W3C trace context (a JSON object), when the
server stamped one from the inbound traceparent/tracestate headers.
Used to populate the change-log trace_context JSONB column so an outbox
row carries enough to re-propagate the distributed trace (#375). None when
the request carried no valid trace context.
Sourcepub fn with_trace_context(self, trace_context: Value) -> Self
pub fn with_trace_context(self, trace_context: Value) -> Self
Stamp the originating request’s full W3C trace context (a JSON object) onto
the context (carried in attributes). Read back via
trace_context.
Sourcepub fn actor_type(&self) -> ActorType
pub fn actor_type(&self) -> ActorType
The request’s actor classification (#390). Derived at
from_user; ActorType::HumanUser when unset (e.g. a
context built directly without derivation).
Sourcepub fn with_actor_type(self, actor_type: ActorType) -> Self
pub fn with_actor_type(self, actor_type: ActorType) -> Self
Stamp the request’s ActorType onto the context (carried in
attributes). Read back via actor_type.
Sourcepub fn acting_for(&self) -> Option<Uuid>
pub fn acting_for(&self) -> Option<Uuid>
The delegated user (the human a delegated agent acts for), when the request
carried an RFC 8693 act claim (#390). None for a non-delegated request,
or when the underlying subject was not UUID-shaped.
Sourcepub fn with_acting_for(self, acting_for: Option<Uuid>) -> Self
pub fn with_acting_for(self, acting_for: Option<Uuid>) -> Self
Stamp the delegated user’s UUID onto the context (carried in attributes).
None removes any prior stamp. Read back via acting_for.
Sourcepub fn is_expired(&self) -> bool
pub fn is_expired(&self) -> bool
Sourcepub const fn is_multi_tenant(&self) -> bool
pub const fn is_multi_tenant(&self) -> bool
Check if the context has a tenant ID (multi-tenancy enabled).
§Returns
true if tenant_id is present, false otherwise.
Sourcepub fn with_role(self, role: String) -> Self
pub fn with_role(self, role: String) -> Self
Set or override a role (for testing or runtime role modification).
Sourcepub fn with_scopes(self, scopes: Vec<String>) -> Self
pub fn with_scopes(self, scopes: Vec<String>) -> Self
Set or override scopes (for testing or runtime permission modification).
Sourcepub fn with_tenant(self, tenant_id: impl Into<TenantId>) -> Self
pub fn with_tenant(self, tenant_id: impl Into<TenantId>) -> Self
Set tenant ID (for multi-tenancy).
Sourcepub fn with_attribute(self, key: String, value: Value) -> Self
pub fn with_attribute(self, key: String, value: Value) -> Self
Set a custom attribute (for testing or runtime attribute addition).
Sourcepub fn can_access_scope(
&self,
security_config: &SecurityConfig,
required_scope: &str,
) -> bool
pub fn can_access_scope( &self, security_config: &SecurityConfig, required_scope: &str, ) -> bool
Check if user can access a field based on role definitions.
Takes a required scope and checks if any of the user’s roles grant that scope.
§Arguments
security_config- Security config from compiled schema with role definitionsrequired_scope- Scope required to access the field (e.g., “read:User.email”)
§Returns
true if user’s roles grant the required scope, false otherwise.
§Example
// Requires: a SecurityConfig from a compiled schema.
// See: tests/integration/ for runnable examples.
let can_access = context.can_access_scope(&config, "read:User.email");Trait Implementations§
Source§impl Clone for SecurityContext
impl Clone for SecurityContext
Source§fn clone(&self) -> SecurityContext
fn clone(&self) -> SecurityContext
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more