Input Controls
CJIS Mode
cjis-mode lets a request through only when its caller has a verified identity with a short remaining credential lifetime and strong enough authentication, such as MFA. It can also require that every access is written to the local gateway log.
The gateway checks assurance claims that your identity system issued. It does not prompt for MFA, and it cannot turn an ordinary application token into an MFA identity. The control checks identity only. It does not examine criminal-justice content or give you a complete compliance process.
Configuration
pack:
name: cjis-mode-example
version: 1.0.0
enabled: true
policies:
chain:
- cjis-mode
policy:
cjis-mode:
require_auth: true
access_logging: true
session_timeout_minutes: 30
required_assurance: multi_factorVerify identity before rollout
The offline test runner has no verified identity, so test through a test agent with credentials from your identity system. With the configuration above:
| Caller identity | Result |
|---|---|
| No verified identity | Rejected by authentication, or cjis.auth_required |
| Verified, 45 minutes left on the proof | cjis.session_freshness_exceeded |
| Verified, 20 minutes left, token-only assurance | cjis.mfa_required |
| Subject, organization, 30 minutes or less left, sufficient assurance | cjis.ok, if the access log write also succeeds |
Read the nested cjis-mode result. User or role headers never count as verified identity. Keep this control off shared gateways until your callers' credentials meet these requirements.
Fields
| Field | Type | Default | Description |
|---|---|---|---|
require_auth | boolean | true | Recorded in the details. A request without verified identity is blocked with either value. |
access_logging | boolean | true | Writes a cjis.access record to the local gateway event log for each allowed request and each request blocked for missing identity |
session_timeout_minutes | integer | 30 | Maximum remaining lifetime of the proof, from 1 to 1440. Values outside the range are moved to the nearest limit. |
required_assurance | string | multi_factor | Minimum assurance: multi_factor or phishing_resistant |
Lint rejects the removed fields at_rest_encryption, session_timeout_seconds, and encryption_at_rest.
How it works
The checks run in this order. The first failure blocks with its reason code.
- The gateway must have validated the identity from an API token, the gateway runtime token, or a JWKS-verified signed assertion. Unvalidated headers do not count. Otherwise:
cjis.auth_required. - The identity must have a subject:
cjis.subject_required. - It must have an organization:
cjis.organization_required. - The proof must have an expiry time:
cjis.proof_expiry_required. - The proof must not have expired:
cjis.proof_expired. - Its remaining lifetime must not be more than
session_timeout_minutes:cjis.session_freshness_exceeded. - The assurance must be at least
required_assurance, in the ordertoken,single_factor,multi_factor,phishing_resistant:cjis.mfa_required. - With
access_logging, thecjis.accessrecord must be written:cjis.audit_delivery_failed. - The request is allowed with
cjis.ok.
An allowed request's details contain subject, org_id, proof_method, assurance_level, expires_at, and the four configured values.
Phase and verdicts
| Item | Value |
|---|---|
| Phase | input |
| Request families | All |
| Verdicts | allow, block |
Only cjis.ok allows. Every other code blocks:
| Reason code | Cause |
|---|---|
cjis.ok | All checks passed |
cjis.auth_required | No verified identity |
cjis.subject_required | No subject |
cjis.organization_required | No organization |
cjis.proof_expiry_required | Proof without an expiry time |
cjis.proof_expired | Proof already expired |
cjis.session_freshness_exceeded | Proof expires more than session_timeout_minutes from now |
cjis.mfa_required | Assurance below required_assurance |
cjis.audit_delivery_failed | The cjis.access record could not be written |
cjis.required_assurance_invalid | Unknown required_assurance in the runtime configuration |
cjis.unproven_option | Removed field encryption_at_rest in the runtime configuration |
Limits and failure behavior
- The assurance level comes from token validation claims or the signed assertion. The gateway does not perform MFA.
- Long-lived tokens fail. With the default 30 minutes, a proof that expires in 31 minutes or more is blocked. Issue short-lived credentials for CJIS workloads.
- If the
cjis.accessrecord cannot be written to the local durable event log, the request is blocked. The control does not fail open. - Besides allowed requests, only requests blocked for missing identity get a
cjis.accessrecord. - The prompt and response are not examined. Add
case-privacyorpii-detectorfor content. - An unknown
required_assuranceblocks every request. Lint rejects it first.
Next steps
- Case Privacy: redact case identifiers in the same chain.
- RBAC: tools and data sensitivity by verified role.
- Investigate a Blocked Request: trace a
cjis.*block.