Skip to content

Feature support

Feature support

Everything that is not a wire protocol. For the RFC-by-RFC record see Standards & conformance; for the grading vocabulary — Full, Partial, Contract only, Host-supplied, No — see Capabilities.

Identity & authentication

Capability Grade Notes
Global subjects with a pluggable user model Full The host's own User model is resolved through config; the package owns the schema.
Password authentication Full Framework hasher (bcrypt/argon2id), constant-time failure path, rehash-on-login.
Password policy — length, reuse history, expiry, lockout, MFA and SSO mandates Full An environment sets the floor; an organization may only tighten it, never negotiate below it. Minimum length defaults to 12. Reuse history, expiry and lockout each default to off until you set them.
Breached-password screening Contract only The shipped default answers "not breached" for every password. See the caveat in Standards.
Password complexity classes No
Bulk user import with lazy hash migration Full CSV or JSON via cbox-id:users:import; foreign hashes are refused unless you bind a verifier for the format, then upgraded to the platform hasher on first successful login.
Sessions — absolute TTL and idle timeout Full 8 hours and 30 minutes by default; amr recorded on the session.
"Remember me" persistent login No
Step-up / sudo re-authentication Host-supplied The package records auth_time and amr and stamps acr so your app can decide, and gives you MFA verification primitives. It ships no freshness window, no sudo mode and no re-auth challenge.
TOTP second factor Partial SHA-1, 6 digits, 30 s, ±1 step — fixed. Secrets sealed at rest, replay blocked.
WebAuthn / passkeys Partial Real verification; ES256 and RS256 only; none and self-attested packed only. Inert until rp_id and origin are configured. Challenge issuance is host-supplied.
Recovery / backup codes Full
Magic-link email sign-in Full Hash-only single-use token with a TTL.
Password reset Full Hash-only single-use token, TTL, anti-enumeration, revokes every session on reset.
Email verification Full Hash-only single-use token, TTL, stale-address guard.
One-time passcodes (OTP) Partial Keyed HMAC at rest (HKDF subkey off the master key), decoy hash for uniform timing, per-recipient and per-IP rate limits, per-challenge attempt cap. Only the email channel ships — plus a log channel for development and a null channel.
SMS / voice / push OTP Contract only OtpChannel is the extension point; no driver and no provider SDK ships.
Login lockout Partial Implemented, serialized under a row lock, audited — but the threshold defaults to null, so it is off until a policy sets it. Window and duration are fixed at 15 minutes.
Federated sign-in and explicit account linking Full Provider-agnostic FederatedPrincipal. A federated identity is never merged into an existing account by email; that path is refused so linking stays deliberate.
Named social providers (Google, GitHub, Microsoft buttons) Host-supplied The framework provides the provider-agnostic linking path only.

Authorization

Capability Grade Notes
Roles and permissions, scoped per organization Full Uniqueness is per (organization, client_id, role name), so two apps can own a role of the same name.
Hierarchy-aware roll-down Full A role granted at an ancestor organization applies to its descendants, via a closure table.
Wildcard permissions (billing.*) No Permission matching is exact-name equality.
Role inherits role No Only organization hierarchy inherits; there is no role graph.
Relationship-based authorization (ReBAC) Partial A real tuple store with recursive userset expansion, cycle protection and a depth limit of 12. Not cached — every check is live queries, two per node. No policy DSL, and no compatibility with any external authorization-service wire protocol.
Policy decision point Partial The PDP decides from ReBAC tuples only. RBAC permission checks run on their own path and do not pass through it — treat them as two authorization systems that meet at the decision endpoint, not one.
Entitlements fed by your billing engine Full Version-tagged cache invalidation, environment-scoped keys, and a random re-seed on counter loss so a stale snapshot cannot resurrect. Never holds billing state.
Authorization decision endpoint (POST /oauth/decisions) Full Permission and entitlement checks in one round trip, batch capped (default 50) so one request cannot become an unbounded number of queries.
Entitlement claims embedded in the access token Full Coarse entitlements ride as an ent claim with a staleness signal; instant-critical ones stay live.
Bring-your-own RBAC driver Contract only Switching the driver away from builtin binds stubs that refuse every call until you supply an adapter.
Group → role mapping from the directory Full SCIM group membership changes reconcile role assignments.
App-declared role manifests Full Apps publish their own roles/permissions over HTTP; fetching is SSRF-guarded and syncs hourly.
XACML No

Organizations & tenancy

Capability Grade Notes
Environments as a hard identity boundary Full Own users, own keys, own issuer. Deny-by-default: no environment in context means zero rows.
Organizations, memberships, invitations Full Invitations are explicit-acceptance — creating one grants nothing. Last-owner removal is refused.
Reseller / parent hierarchy Full Closure table with loop-refusing subtree moves.
Groups and resource grants Full Both write ReBAC tuples.
Custom domains Partial DNS TXT challenge, verification, and promotion to issuer host. Deliberately TLS-agnostic — certificate issuance is yours.
Home-realm discovery (email domain → SSO connection) Partial The lookup primitive ships and is environment-scoped, but there is no endpoint and no caller — routing a login by email domain is yours to wire.
User API tokens Full Capped at the issuing member's role.
Platform control plane — operators, accounts, projects Full Accounts sit above the environment boundary; account members are ordinary subjects in the platform-root environment rather than a second credential store. Signed, expiring, purpose-pinned handoff into a tenant environment.

Directory & provisioning

Capability Grade Notes
Inbound SCIM 2.0 server Partial See Standards for the per-section detail.
Directory pull connectors Full Google Workspace (Admin SDK) and Microsoft Entra (Graph). Both normalise into the same value objects and run the same reconciliation as SCIM push. Neither is a SCIM client — they are proprietary REST APIs shaped into SCIM. Both carry a setup guide in the provider catalogue (ProviderCatalog::forDirectory()), so a console can render the same guidance for a directory that it renders for a sign-in connection.
Immediate deprovision Full Deactivation drops membership and revokes sessions immediately.
Outbound SCIM provisioning Partial A generic SCIM 2.0 client against any endpoint, with bearer or client-credentials auth, a durable outbox, retries, dead-lettering, per-connection circuit breaker, and a resolve-once IP-pinned SSRF guard. Users only — no group or membership push. No vendor-specific connectors.
Deprovision policy Full Per connection: deactivate (active: false) or delete.

Governance

Capability Grade Notes
Access-certification campaigns Full Snapshot, certify/revoke, apply on close. Revocations are genuinely applied, and a refusal (last owner, say) is recorded with its reason rather than dropped. Un-reviewed items default to revoke. Overdue campaigns close on a schedule.
Segregation of Duties Partial Pre-grant gate plus conflict scanning, with reasoned decisions. Ignores hierarchy-inherited roles.
Scope of both Partial RBAC role assignments and organization memberships only. Entitlements and ReBAC tuples are out of scope — ReBAC tuples have no enumeration surface to certify against.

Audit & observability

Capability Grade Notes
Append-only hash-chained audit trail Full SHA-256(canonical payload ‖ previous hash), one chain per environment and scope, with the environment id inside the hash so a row cannot be moved between environments undetected. Appends serialize on an anchor row and retry on unique-constraint collision.
Signed checkpoints Partial A JWS over {scope, up_to_sequence, root_hash} closes the tail-truncation hole that a bare chain leaves open. cbox-id:audit:checkpoint signs every advanced chain and can run daily on the scheduler — but the schedule ships off (audit.checkpoint.schedule, default false), because the first signature forecloses a planned one-time re-chain. Until you enable it or call for a checkpoint yourself, deletion of the chain's tail is not detectable.
Tamper-proof storage No This is tamper-evident, not tamper-proof: no WORM storage, no external notarization or transparency log, and no per-entry signature. Someone with database write access can still delete rows — the chain and checkpoints are what make it visible.
Audit query and SIEM pull stream Full Filtered, paginated reads plus a sequence cursor.
Outbound SIEM streaming Partial Transactional outbox committed with the audit entry, at-least-once, pumped every minute. One transport: HTTP(S). Splunk HEC, Elastic ECS, GELF 1.1, ArcSight CEF and generic JSON are five formats over it. No file, S3, syslog-transport or OCSF sink.
Retention / pruning Full cbox-id:prune sweeps ten tables with per-table defaults and a dry-run mode. audit_logs is deliberately never pruned — pruning below a checkpoint would break verification, and pruning up to one would remove the anchor.

Events, webhooks & hooks

Capability Grade Notes
Transactional outbox for domain events Full Emitted inside the caller's transaction, so a rolled-back change cannot leave an event behind.
Delivery guarantee Partial At-least-once, explicitly — subscribers must be idempotent. Exactly-once is neither claimed nor implemented.
Relay backlog observability Full Logged every pass, warns above a threshold, and cbox-id:events:backlog exits non-zero on demand for alerting.
Outbound webhooks Full Asynchronous, uniqueness-locked, exponential backoff to a 12-attempt dead letter, stranded-delivery rescue, per-endpoint circuit breaker, gap-free per-endpoint sequence, HTTPS-only DNS-pinned SSRF guard.
Webhook signature Full, proprietary HMAC-SHA256 over "{timestamp}.{body}", sent as X-Cbox-Timestamp and X-Cbox-Signature: t=…,v1=…. This is not the Standard Webhooks specification — do not point a spec-compliant verifier at it.
Webhook replay protection Partial The timestamp is signed so a receiver can enforce a tolerance window, but no receiver-side verifier and no tolerance constant ship — that half is yours.
Event catalog Full 27 typed event types plus a * wildcard subscription.
Inline hooks (external actions) Full Six points — token minting, post-login, pre/post registration, pre/post password change — each with its own fail policy (token_minting, pre_registration and pre_password_change fail closed). In-process handlers or signed, SSRF-guarded HTTP calls with pinned DNS and no redirects. A deny at a non-vetoable point is audited and folded to an allow rather than silently ignored.

Cryptography & secrets

Capability Grade Notes
Envelope encryption for secrets at rest Full XChaCha20-Poly1305-IETF (libsodium), random nonce per message, bound to a context string as AEAD additional data. Not AES-GCM.
Signing key management and rotation Full RSA-2048, P-256 or Ed25519; private keys sealed per-kid; cbox-id:keys:rotate with an Active→Rotating→Retired overlap so in-flight tokens keep verifying.
Master-key rotation No There is no re-encrypt/rewrap routine. The vault's key_version column is written as a constant and never read. Plan master-key custody accordingly.
HSM / KMS integration Contract only SecretBox is the swap point; no AWS KMS, Vault or PKCS#11 implementation ships.
Token vault for downstream credentials Full Seals third-party credentials and brokers short-lived, deny-by-default leases to clients. Uniform refusal with no enumeration oracle; the real reason goes to the audit log only. Per-grant TTL can only shorten the default. Secret rotation is supported (master-key rotation is not — see above).

Operations & tooling

Capability Grade Notes
Artisan commands Full Fifteen, including cbox-id:install, cbox-id:doctor, cbox-id:users:import, cbox-id:directory:sync, cbox-id:provisioning:sync, cbox-id:keys:rotate, cbox-id:events:relay, cbox-id:events:backlog, cbox-id:prune, cbox-id:audit:checkpoint, cbox-id:audit-streams:pump, cbox-id:governance:close-overdue.
Scheduled work Full Manifest sync, audit-stream pump, governance auto-close and the event relay all register themselves, config-gated and withoutOverlapping. See Operationsthe platform delivers nothing without a queue worker and scheduler running.
Usage metering Full Per-day, per-environment, per-organization counters fed off the outbox, with a reconciler for drift. Metering never enforces — enforcement belongs to entitlements.
Testing helpers Full Every module ships InteractsWith* traits and fakes, and the package's own suite uses them.
Database engines Partial SQLite, MySQL 8.0.13+, PostgreSQL 14+ and MariaDB 10.2+ are green in CI — genuinely, since the engines job moved to a runner where it can reach its service containers. SQL Server has never been run. See Requirements — that page is the authority, not this row.
Telemetry / metrics runtime No Deliberate: a library must not force an observability stack on its host.
Admin console, hosted login, consent screen Host-supplied This package is UI-free.

Client SDKs

First-party client libraries wrap sign-in, the profile/account redirect, back-channel token exchange, webhook-signature verification, the Token Vault and app-manifest publishing. They are separate packages — installing cboxdk/laravel-id does not install them, and their own repositories are the authority on what they support.

SDK Package
JavaScript / TypeScript @cboxdk/id-js
React @cboxdk/id-react
Vue / Nuxt @cboxdk/id-vue, @cboxdk/id-nuxt
Python cbox-id-client
Go github.com/cboxdk/id-go
Laravel / PHP cboxdk/laravel-id-client