pub struct AuthStore { /* private fields */ }Expand description
Central in-process authority for auth state.
All mutations are guarded by RwLocks so the store is Send + Sync.
Implementations§
Source§impl AuthStore
impl AuthStore
pub fn new(config: AuthConfig) -> AuthStore
pub fn configure_control_events( &self, ledger: Arc<dyn ControlEventLedger>, config: ControlEventConfig, )
Sourcepub fn with_vault(
config: AuthConfig,
pager: Arc<Pager>,
passphrase: Option<&str>,
) -> Result<AuthStore, AuthError>
pub fn with_vault( config: AuthConfig, pager: Arc<Pager>, passphrase: Option<&str>, ) -> Result<AuthStore, AuthError>
Create an AuthStore backed by encrypted vault pages inside the
main .rdb database file.
If vault pages already exist, their contents are loaded and restored into the in-memory store. All subsequent mutations are automatically persisted to the vault pages via the pager.
pub fn config(&self) -> &AuthConfig
pub fn is_enabled(&self) -> bool
Sourcepub fn needs_bootstrap(&self) -> bool
pub fn needs_bootstrap(&self) -> bool
Returns true when no users exist yet and bootstrap hasn’t been sealed.
Sourcepub fn is_bootstrapped(&self) -> bool
pub fn is_bootstrapped(&self) -> bool
Whether bootstrap has already been performed (sealed).
Sourcepub fn bootstrap(
&self,
username: &str,
password: &str,
) -> Result<BootstrapResult, AuthError>
pub fn bootstrap( &self, username: &str, password: &str, ) -> Result<BootstrapResult, AuthError>
Bootstrap the first admin user. One-shot, irreversible.
Uses an atomic compare-exchange to guarantee that even under concurrent calls, only the first one succeeds. Once sealed, all subsequent calls fail immediately – there is no undo.
When a vault/pager is configured, a certificate-based keypair is
generated and the vault is re-encrypted with the certificate-derived
key. The certificate hex string is returned in BootstrapResult
so the admin can save it.
pub fn bootstrap_with_control_events( &self, username: &str, password: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<BootstrapResult, AuthError>
Sourcepub fn bootstrap_system_admin(
&self,
username: &str,
password: &str,
) -> Result<BootstrapResult, AuthError>
pub fn bootstrap_system_admin( &self, username: &str, password: &str, ) -> Result<BootstrapResult, AuthError>
Bootstrap the first admin with system_owned = true and platform
scope (tenant = None). The resulting principal carries both
principal_is_system_owned and principal_is_platform_scoped,
which is what #649’s ManagedConfigGate requires before allowing
writes to managed config keys. Used by the production bootstrap
preset (issue #650).
Sourcepub fn bootstrap_from_env(&self) -> Option<BootstrapResult>
pub fn bootstrap_from_env(&self) -> Option<BootstrapResult>
Auto-bootstrap from environment variables if no users exist.
Checks REDDB_USERNAME and REDDB_PASSWORD. If both are set and
the user store is empty, creates the first admin user automatically.
This mirrors the Docker pattern (MYSQL_ROOT_PASSWORD, etc.).
Returns Some(BootstrapResult) if bootstrapped, None if skipped.
Sourcepub fn is_vault_backed(&self) -> bool
pub fn is_vault_backed(&self) -> bool
True when this store has an encrypted vault and pager wired in.
Sourcepub fn vault_kv_get(&self, key: &str) -> Option<String>
pub fn vault_kv_get(&self, key: &str) -> Option<String>
Read a value from the vault KV store. Returns None if not set.
Sourcepub fn vault_kv_snapshot(&self) -> HashMap<String, String>
pub fn vault_kv_snapshot(&self) -> HashMap<String, String>
Snapshot vault KV values for statement-local secret resolution.
Sourcepub fn vault_kv_export_encrypted(&self) -> Result<Option<String>, AuthError>
pub fn vault_kv_export_encrypted(&self) -> Result<Option<String>, AuthError>
Export vault KV as an encrypted logical blob for JSONL dump/restore.
Returns None when the vault has no KV entries.
Sourcepub fn vault_kv_try_import(
&self,
entries: HashMap<String, String>,
) -> Result<usize, AuthError>
pub fn vault_kv_try_import( &self, entries: HashMap<String, String>, ) -> Result<usize, AuthError>
Merge imported vault KV entries and fail if the encrypted vault write cannot be made durable.
Sourcepub fn vault_kv_try_import_placeholders(
&self,
keys: &[String],
) -> Result<usize, AuthError>
pub fn vault_kv_try_import_placeholders( &self, keys: &[String], ) -> Result<usize, AuthError>
Import false placeholders for secrets whose encrypted payload could not be decrypted during logical restore.
Sourcepub fn vault_kv_set(&self, key: String, value: String)
pub fn vault_kv_set(&self, key: String, value: String)
Write a value to the vault KV store, persisting to disk.
Sourcepub fn vault_kv_try_set(
&self,
key: String,
value: String,
) -> Result<(), AuthError>
pub fn vault_kv_try_set( &self, key: String, value: String, ) -> Result<(), AuthError>
Write a value to the vault KV store and fail if the vault write cannot be made durable.
Sourcepub fn vault_kv_delete(&self, key: &str) -> bool
pub fn vault_kv_delete(&self, key: &str) -> bool
Delete a value from the vault KV store. Returns true if it existed.
Sourcepub fn vault_kv_try_delete(&self, key: &str) -> Result<bool, AuthError>
pub fn vault_kv_try_delete(&self, key: &str) -> Result<bool, AuthError>
Delete a value from the vault KV store and fail if the vault write cannot be made durable.
Sourcepub fn vault_kv_keys(&self) -> Vec<String>
pub fn vault_kv_keys(&self) -> Vec<String>
List all keys in the vault KV store.
Sourcepub fn vault_secret_key(&self) -> Option<[u8; 32]>
pub fn vault_secret_key(&self) -> Option<[u8; 32]>
Convenience: get the 32-byte secret key for Value::Secret encryption.
Generated on first boot and stored at red.secret.aes_key.
Sourcepub fn ensure_vault_secret_key(&self)
pub fn ensure_vault_secret_key(&self)
Generate and store the AES-256 secret key on first boot if not present.
Sourcepub fn create_user(
&self,
username: &str,
password: &str,
role: Role,
) -> Result<User, AuthError>
pub fn create_user( &self, username: &str, password: &str, role: Role, ) -> Result<User, AuthError>
Create a new platform-scoped user (tenant_id = None).
For tenant-scoped creation, use Self::create_user_in_tenant.
pub fn create_user_with_control_events( &self, username: &str, password: &str, role: Role, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<User, AuthError>
Sourcepub fn create_user_in_tenant(
&self,
tenant_id: Option<&str>,
username: &str,
password: &str,
role: Role,
) -> Result<User, AuthError>
pub fn create_user_in_tenant( &self, tenant_id: Option<&str>, username: &str, password: &str, role: Role, ) -> Result<User, AuthError>
Create a user under the given tenant scope. tenant_id == None
produces a platform-wide user. (tenant, username) is the
uniqueness key — the same username may exist independently
under multiple tenants.
pub fn create_user_in_tenant_with_control_events( &self, tenant_id: Option<&str>, username: &str, password: &str, role: Role, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<User, AuthError>
pub fn create_system_user( &self, username: &str, password: &str, role: Role, tenant_id: Option<&str>, ) -> Result<User, AuthError>
Sourcepub fn lookup_scram_verifier(&self, id: &UserId) -> Option<ScramVerifier>
pub fn lookup_scram_verifier(&self, id: &UserId) -> Option<ScramVerifier>
Look up a user’s SCRAM verifier by full UserId.
The wire handshake passes the tenant resolved from the session
(or None for the bootstrap admin) so cross-tenant collisions
never authenticate the wrong identity.
Sourcepub fn lookup_scram_verifier_global(
&self,
username: &str,
) -> Option<ScramVerifier>
pub fn lookup_scram_verifier_global( &self, username: &str, ) -> Option<ScramVerifier>
Backwards-compatible shim for the v2 wire bootstrap path: looks
up a user by username assuming the platform (tenant=None)
scope. Use this only where the handshake hasn’t yet learned the
caller’s tenant.
Sourcepub fn list_users(&self) -> Vec<User>
pub fn list_users(&self) -> Vec<User>
Return all users (password hashes redacted).
The synthetic crate::auth::self_lock_guard::PLATFORM_OWNER_USERNAME
principal is filtered out — it is a policy-graph anchor, not an
operator-visible account.
Sourcepub fn list_users_scoped(
&self,
tenant_filter: Option<Option<&str>>,
) -> Vec<User>
pub fn list_users_scoped( &self, tenant_filter: Option<Option<&str>>, ) -> Vec<User>
Return users restricted to a tenant scope.
tenant_filter:
Nonelisting inSome(None)— only platform usersSome(Some("acme"))— only users in tenantacmeNoneargument — all users (admin-only callers)
Sourcepub fn principal_is_system_owned(&self, principal: &UserId) -> bool
pub fn principal_is_system_owned(&self, principal: &UserId) -> bool
Look up a single user by (tenant, username). Password hash
is redacted.
Whether the given principal’s user record is system-owned. Returns
false for unknown principals — an absent record is never treated as
operator-owned. Used to populate EvalContext::principal_is_system_owned
on the runtime authorization hot path.
pub fn get_user(&self, tenant_id: Option<&str>, username: &str) -> Option<User>
Sourcepub fn delete_user(&self, username: &str) -> Result<(), AuthError>
pub fn delete_user(&self, username: &str) -> Result<(), AuthError>
Delete a platform-scoped user (tenant_id = None) and revoke
all of their API keys + sessions.
For tenant-scoped deletes, use Self::delete_user_in_tenant.
pub fn delete_user_with_control_events( &self, username: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
Sourcepub fn delete_user_in_tenant(
&self,
tenant_id: Option<&str>,
username: &str,
) -> Result<(), AuthError>
pub fn delete_user_in_tenant( &self, tenant_id: Option<&str>, username: &str, ) -> Result<(), AuthError>
Delete a user identified by (tenant_id, username) and revoke
all of their API keys + sessions.
pub fn delete_user_in_tenant_with_control_events( &self, tenant_id: Option<&str>, username: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
Sourcepub fn change_password(
&self,
username: &str,
old_password: &str,
new_password: &str,
) -> Result<(), AuthError>
pub fn change_password( &self, username: &str, old_password: &str, new_password: &str, ) -> Result<(), AuthError>
Change password (requires the old password). Defaults to
platform tenant; use Self::change_password_in_tenant for
scoped users.
pub fn change_password_with_control_events( &self, username: &str, old_password: &str, new_password: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
pub fn change_password_in_tenant( &self, tenant_id: Option<&str>, username: &str, old_password: &str, new_password: &str, ) -> Result<(), AuthError>
pub fn change_password_in_tenant_with_control_events( &self, tenant_id: Option<&str>, username: &str, old_password: &str, new_password: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
Sourcepub fn change_role(
&self,
username: &str,
new_role: Role,
) -> Result<(), AuthError>
pub fn change_role( &self, username: &str, new_role: Role, ) -> Result<(), AuthError>
Change a user’s role (admin-only operation). Defaults to platform
tenant; use Self::change_role_in_tenant for scoped users.
pub fn change_role_in_tenant( &self, tenant_id: Option<&str>, username: &str, new_role: Role, ) -> Result<(), AuthError>
pub fn change_role_in_tenant_with_control_events( &self, tenant_id: Option<&str>, username: &str, new_role: Role, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
Sourcepub fn authenticate(
&self,
username: &str,
password: &str,
) -> Result<Session, AuthError>
pub fn authenticate( &self, username: &str, password: &str, ) -> Result<Session, AuthError>
Verify credentials for a platform-tenant user (tenant_id = None)
and create a session. For tenant-scoped login use
Self::authenticate_in_tenant.
When a keypair is available (certificate-based seal), session tokens are signed with the master secret so the server can verify they were genuinely issued by this vault instance.
Sourcepub fn authenticate_in_tenant(
&self,
tenant_id: Option<&str>,
username: &str,
password: &str,
) -> Result<Session, AuthError>
pub fn authenticate_in_tenant( &self, tenant_id: Option<&str>, username: &str, password: &str, ) -> Result<Session, AuthError>
Verify credentials for (tenant_id, username, password) and
create a session. Tenant-aware: alice@acme and alice@globex
authenticate independently.
Sourcepub fn validate_token(&self, token: &str) -> Option<(String, Role)>
pub fn validate_token(&self, token: &str) -> Option<(String, Role)>
Validate a token (session or API key).
Returns (username, role) if valid, None otherwise. Tenant
scope is dropped here for compatibility with the bulk of the
existing caller surface (routing, gRPC control, redwire). Use
Self::validate_token_full when the caller needs the
resolved UserId (e.g. to pin CURRENT_TENANT()).
Sourcepub fn validate_token_full(&self, token: &str) -> Option<(UserId, Role)>
pub fn validate_token_full(&self, token: &str) -> Option<(UserId, Role)>
Tenant-aware token validation. Returns the resolved UserId
(which carries the tenant) and the granted Role.
Sourcepub fn create_api_key(
&self,
username: &str,
name: &str,
role: Role,
) -> Result<ApiKey, AuthError>
pub fn create_api_key( &self, username: &str, name: &str, role: Role, ) -> Result<ApiKey, AuthError>
Create a persistent API key for a platform-tenant user.
For tenant-scoped users use Self::create_api_key_in_tenant.
pub fn create_api_key_with_control_events( &self, username: &str, name: &str, role: Role, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<ApiKey, AuthError>
pub fn create_api_key_in_tenant( &self, tenant_id: Option<&str>, username: &str, name: &str, role: Role, ) -> Result<ApiKey, AuthError>
pub fn create_api_key_in_tenant_with_control_events( &self, tenant_id: Option<&str>, username: &str, name: &str, role: Role, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<ApiKey, AuthError>
pub fn revoke_api_key_with_control_events( &self, key: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
Sourcepub fn revoke_session(&self, token: &str)
pub fn revoke_session(&self, token: &str)
Revoke a session token.
Sourcepub fn purge_expired_sessions(&self) -> usize
pub fn purge_expired_sessions(&self) -> usize
Purge expired sessions (housekeeping).
Sourcepub fn grant(
&self,
granter: &UserId,
granter_role: Role,
principal: GrantPrincipal,
resource: Resource,
actions: Vec<Action>,
with_grant_option: bool,
tenant: Option<String>,
) -> Result<(), AuthError>
pub fn grant( &self, granter: &UserId, granter_role: Role, principal: GrantPrincipal, resource: Resource, actions: Vec<Action>, with_grant_option: bool, tenant: Option<String>, ) -> Result<(), AuthError>
Persist a grant. Returns Forbidden when the granting user is
not Admin or attempts a cross-tenant grant.
Sourcepub fn revoke(
&self,
granter_role: Role,
principal: &GrantPrincipal,
resource: &Resource,
actions: &[Action],
) -> Result<usize, AuthError>
pub fn revoke( &self, granter_role: Role, principal: &GrantPrincipal, resource: &Resource, actions: &[Action], ) -> Result<usize, AuthError>
Drop matching grants from a principal. Returns the number of grants removed.
Sourcepub fn visible_collections_for_scope(
&self,
tenant: Option<&str>,
role: Role,
principal: &str,
all_collections: &[String],
) -> HashSet<String>
pub fn visible_collections_for_scope( &self, tenant: Option<&str>, role: Role, principal: &str, all_collections: &[String], ) -> HashSet<String>
Compute the set of collection ids a given (tenant, role)
scope can read, consulting the explicit grant table. The result
is cached for super::scope_cache::DEFAULT_TTL (60s) and
invalidated on every GRANT/REVOKE/policy/collection mutation
that could change the answer.
all_collections is the full list of collection ids known to
the storage layer. The runtime hands it in so this module stays
decoupled from the storage crate. Each collection passes through
check_grant(SELECT) under a synthetic (principal, role, tenant) view. The cache key includes principal because direct
grants can differ between users that share the same tenant and
role.
Sourcepub fn auth_cache_stats(&self) -> AuthCacheStats
pub fn auth_cache_stats(&self) -> AuthCacheStats
Stats probe required by issue #119 — exposes hit/miss counts and invalidations for the visible-collections cache so metrics pipelines can compute a hit rate.
Sourcepub fn invalidate_visible_collections_cache(&self)
pub fn invalidate_visible_collections_cache(&self)
Drop every cached (tenant, role) entry. Called from CREATE
POLICY / DROP POLICY / DROP COLLECTION paths where the affected
tenant set is unknown.
Sourcepub fn invalidate_visible_collections_for_tenant(&self, tenant: Option<&str>)
pub fn invalidate_visible_collections_for_tenant(&self, tenant: Option<&str>)
Drop cached entries for one tenant. Called from GRANT / REVOKE where the principal’s tenant is known.
Sourcepub fn effective_grants(&self, uid: &UserId) -> Vec<Grant>
pub fn effective_grants(&self, uid: &UserId) -> Vec<Grant>
Snapshot of every grant the principal effectively has, including
Public grants. Audit / introspection helper.
Sourcepub fn check_grant(
&self,
ctx: &AuthzContext<'_>,
action: Action,
resource: &Resource,
) -> Result<(), AuthzError>
pub fn check_grant( &self, ctx: &AuthzContext<'_>, action: Action, resource: &Resource, ) -> Result<(), AuthzError>
Run a privilege check using the in-memory grant tables. Returns
Ok(()) on allow, Err(AuthzError) on deny.
Sourcepub fn set_user_attributes(
&self,
uid: &UserId,
attrs: UserAttributes,
) -> Result<(), AuthError>
pub fn set_user_attributes( &self, uid: &UserId, attrs: UserAttributes, ) -> Result<(), AuthError>
Replace the attribute record for uid.
Sourcepub fn user_attributes(&self, uid: &UserId) -> UserAttributes
pub fn user_attributes(&self, uid: &UserId) -> UserAttributes
Read the attributes for uid. Returns Default::default() for
users that have never been altered.
pub fn add_user_to_group( &self, uid: &UserId, group: &str, ) -> Result<(), AuthError>
pub fn remove_user_from_group( &self, uid: &UserId, group: &str, ) -> Result<(), AuthError>
Sourcepub fn set_user_enabled(
&self,
uid: &UserId,
enabled: bool,
) -> Result<(), AuthError>
pub fn set_user_enabled( &self, uid: &UserId, enabled: bool, ) -> Result<(), AuthError>
Toggle User.enabled without rotating credentials.
pub fn disable_user( &self, username: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
pub fn disable_user_in_tenant( &self, tenant_id: Option<&str>, username: &str, ctx: &ControlEventCtx<'_>, ledger: &dyn ControlEventLedger, config: ControlEventConfig, ) -> Result<(), AuthError>
Sourcepub fn authenticate_with_attrs(
&self,
tenant_id: Option<&str>,
username: &str,
password: &str,
) -> Result<Session, AuthError>
pub fn authenticate_with_attrs( &self, tenant_id: Option<&str>, username: &str, password: &str, ) -> Result<Session, AuthError>
Authenticate with VALID UNTIL / CONNECTION LIMIT enforcement.
Wraps authenticate_in_tenant and additionally:
- rejects logins after
valid_until, - rejects logins when the live session count would exceed the
connection_limitattribute.
Sourcepub fn decrement_session_count(&self, uid: &UserId)
pub fn decrement_session_count(&self, uid: &UserId)
Decrement the live-session count for uid. Call from session
revoke / expiry paths so CONNECTION LIMIT stays accurate.
Sourcepub fn rehydrate_acl(&self)
pub fn rehydrate_acl(&self)
Re-read the ACL state from vault_kv. Call after vault load /
restore so the in-memory maps reflect the persisted data.
pub fn put_policy_with_control_events( &self, p: Policy, control: &PolicyMutationControl<'_>, ) -> Result<(), AuthError>
pub fn delete_policy_with_control_events( &self, id: &str, control: &PolicyMutationControl<'_>, ) -> Result<(), AuthError>
pub fn attach_policy_with_control_events( &self, principal: PrincipalRef, policy_id: &str, control: &PolicyMutationControl<'_>, ) -> Result<(), AuthError>
pub fn detach_policy_with_control_events( &self, principal: PrincipalRef, policy_id: &str, control: &PolicyMutationControl<'_>, ) -> Result<(), AuthError>
Sourcepub fn put_policy(&self, p: Policy) -> Result<(), AuthError>
pub fn put_policy(&self, p: Policy) -> Result<(), AuthError>
Insert or replace a policy by id. Rejects synthetic ids
(_grant_* / _default_*) so callers can’t hand-write them
from the public API. Use put_policy_internal for synthetic
inserts.
Sourcepub fn put_policy_internal(&self, p: Policy) -> Result<(), AuthError>
pub fn put_policy_internal(&self, p: Policy) -> Result<(), AuthError>
Internal put bypassing the synthetic-namespace guard. Used by
the GRANT translation layer; exposed publicly so integration
tests can register synthetic _grant_* policies without going
through the SQL frontend.
Whether the IAM evaluator should be authoritative for runtime authorization. This flips on the first policy write and remains on after deletes so dropping all policies leaves the instance in default-deny rather than silently returning to role fallback.
Sourcepub fn delete_policy(&self, id: &str) -> Result<(), AuthError>
pub fn delete_policy(&self, id: &str) -> Result<(), AuthError>
Remove a policy and any attachments referencing it.
Sourcepub fn list_policies(&self) -> Vec<Arc<Policy>>
pub fn list_policies(&self) -> Vec<Arc<Policy>>
List all policies (id-sorted for deterministic output).
Sourcepub fn group_policies(&self, group: &str) -> Vec<Arc<Policy>>
pub fn group_policies(&self, group: &str) -> Vec<Arc<Policy>>
List policies directly attached to a group.
Sourcepub fn delete_synthetic_grant_policies(
&self,
principal: &GrantPrincipal,
resource: &Resource,
actions: &[Action],
) -> usize
pub fn delete_synthetic_grant_policies( &self, principal: &GrantPrincipal, resource: &Resource, actions: &[Action], ) -> usize
Delete synthetic policies produced by SQL GRANT translation. REVOKE uses this to keep the IAM lane and the legacy grant table in lock-step.
Sourcepub fn apply_policy_break_glass(
&self,
boot_ts_ms: u128,
) -> Result<(), AuthError>
pub fn apply_policy_break_glass( &self, boot_ts_ms: u128, ) -> Result<(), AuthError>
Apply the REDDB_POLICY_BREAK_GLASS recovery path: install or
refresh the unlock policy, ensure the synthetic platform-owner
user record exists, rebind the unlock policy to it, and emit a
policy.break_glass audit event. Idempotent across reboots.
boot_ts_ms is recorded in the audit event so operators can
correlate the recovery with the boot transcript.
Sourcepub fn attach_policy(
&self,
principal: PrincipalRef,
policy_id: &str,
) -> Result<(), AuthError>
pub fn attach_policy( &self, principal: PrincipalRef, policy_id: &str, ) -> Result<(), AuthError>
Attach a policy to a user or group. Returns an error if the policy id doesn’t exist.
Sourcepub fn detach_policy(
&self,
principal: PrincipalRef,
policy_id: &str,
) -> Result<(), AuthError>
pub fn detach_policy( &self, principal: PrincipalRef, policy_id: &str, ) -> Result<(), AuthError>
Remove a policy attachment from a user or group.
Sourcepub fn effective_policies(&self, user: &UserId) -> Vec<Arc<Policy>>
pub fn effective_policies(&self, user: &UserId) -> Vec<Arc<Policy>>
Resolve the ordered list of effective policies for a user: group attachments first (least specific), then user attachments (most specific). Cached per user.
Sourcepub fn simulate(
&self,
principal: &UserId,
action: &str,
resource: &ResourceRef,
ctx_extras: SimCtx,
) -> SimulationOutcome
pub fn simulate( &self, principal: &UserId, action: &str, resource: &ResourceRef, ctx_extras: SimCtx, ) -> SimulationOutcome
Run the policy simulator for a principal. Synthesises an
EvalContext from the user record + caller-supplied extras.
Sourcepub fn check_policy_authz(
&self,
principal: &UserId,
action: &str,
resource: &ResourceRef,
ctx: &EvalContext,
) -> bool
pub fn check_policy_authz( &self, principal: &UserId, action: &str, resource: &ResourceRef, ctx: &EvalContext, ) -> bool
Production hot-path policy evaluation. Returns true on Allow
/ AdminBypass, false on Deny / DefaultDeny.
This entry point is strict: it never consults the
PolicyEnforcementMode fallback. Governance APIs that gate
admin-tier mutations (managed-config writes, registry
supersedes, managed-policy lifecycle) call this so they cannot
accidentally pick up the lenient LegacyRbac posture. Runtime
hot-path callers that should respect the mode call
AuthStore::check_policy_authz_with_role instead.
Sourcepub fn check_policy_authz_with_role(
&self,
principal: &UserId,
action: &str,
resource: &ResourceRef,
ctx: &EvalContext,
role: Role,
) -> bool
pub fn check_policy_authz_with_role( &self, principal: &UserId, action: &str, resource: &ResourceRef, ctx: &EvalContext, role: Role, ) -> bool
Mode-aware policy evaluation for runtime SQL/HTTP/wire surfaces.
Returns true on Allow/AdminBypass, false on an explicit
Deny. On DefaultDeny (no statement matched) the result
depends on the active PolicyEnforcementMode:
LegacyRbac— defer tolegacy_rbac_decisionusing the caller’srole. This preserves the pre-#712 behaviour where a principal with no attached policy is gated only by their role.PolicyOnly— returnfalse. A principal needs an explicit matchingAllowto be authorized.
An explicit Deny always wins, irrespective of mode and role.
Sourcepub fn enforcement_mode(&self) -> PolicyEnforcementMode
pub fn enforcement_mode(&self) -> PolicyEnforcementMode
Read the active enforcement mode. Cheap (a single RwLock read);
safe to call on the hot path.
Sourcepub fn set_enforcement_mode(
&self,
mode: PolicyEnforcementMode,
) -> PolicyEnforcementMode
pub fn set_enforcement_mode( &self, mode: PolicyEnforcementMode, ) -> PolicyEnforcementMode
Overwrite the active enforcement mode and persist it to the vault KV so the new value survives a restart. Returns the previous value so callers logging a transition (e.g. the boot-time loader, the S5B migration command) can record the before/after.
Sourcepub fn take_legacy_rbac_warn_once(&self) -> bool
pub fn take_legacy_rbac_warn_once(&self) -> bool
Claim the “emit the one-time legacy-RBAC boot warning” token.
Returns true on the first call after construction (or after a
process restart) iff the active mode is LegacyRbac;
returns false on every subsequent call so the boot path can
guarantee the warning is logged at most once per boot.
Sourcepub fn check_column_projection_authz(
&self,
principal: &UserId,
request: &ColumnAccessRequest,
ctx: &EvalContext,
) -> ColumnPolicyOutcome
pub fn check_column_projection_authz( &self, principal: &UserId, request: &ColumnAccessRequest, ctx: &EvalContext, ) -> ColumnPolicyOutcome
Evaluate a resolved table projection through the column policy gate. Query paths should pass already-resolved column names; this helper intentionally does not parse SQL projection syntax.
Sourcepub fn invalidate_all_iam_cache(&self)
pub fn invalidate_all_iam_cache(&self)
Drop every effective-policy cache entry. Called from execution paths that mutate policies/attachments without knowing which users will be affected.
Sourcepub fn rehydrate_iam(&self)
pub fn rehydrate_iam(&self)
Reload IAM state (policies + attachments) from the vault KV.
Replaces the legacy rehydrate_acl reader — pre-1.0 we drop
the old red.acl.* blob format entirely.
Auto Trait Implementations§
impl !Freeze for AuthStore
impl RefUnwindSafe for AuthStore
impl Send for AuthStore
impl Sync for AuthStore
impl Unpin for AuthStore
impl UnsafeUnpin for AuthStore
impl UnwindSafe for AuthStore
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request