Decisions and Attributes

Allowly evaluates one authorization edge:

user + agent + scope + optional resource/context/cost

Your app creates the authorization, stores the authorization_id, calls /v1/check before the agent action, and enforces the returned decision.

Supported decision verbs

These are the live runtime decisions returned by /v1/check.

DecisionMeaningWhat your app should do
allowThe authorization is active and the requested scope is permitted.Run the action.
denyThe action is not permitted.Do not run the action. Branch on reason for UX/support.
confirmThe authorization exists, but this scope requires explicit user confirmation for this action.Prompt the user, approve or deny the nonce, then re-check before running.
escalateThe authorization exists, but this scope requires third-party approval. Pro+ only.Route the escalation to the configured approver, resolve it, then re-check before running.

Reason codes

DecisionReasonWhen it appears
allowauthorization_granted_scope_activeScope is authorized and no confirm step is required.
allowauthorization_granted_via_confirmationUser approved a matching confirm nonce and the confirmation window is still active.
allowauthorization_granted_via_escalationA matching escalation was approved and the approval window is still active.
denyauthorization_not_foundauthorization_id does not exist in this workspace.
denyauthorization_revokedAuthorization was revoked.
denyauthorization_expiredAuthorization expired.
denyscope_not_authorizedScope is not in the authorization, or a scope constraint failed.
denyresource_tombstonedWorkspace tombstone blocks this resource.
denyrate_limit_exceededScope max_per_day counter reached its limit.
denybudget_exceededThe estimated cost would exceed the authorization budget.
denyescalation_rejectedA matching escalation was rejected.
confirmscope_requires_user_confirmationScope is listed in requires_confirm_for and no active confirmation exists.
escalateescalation_requiredScope is listed in requires_escalation_for and no active approval exists.

Authorization attributes

Set these when you create an authorization.

AttributeTypeRequiredNotes
user_idstringyesOpaque internal user ID or SDK email HMAC helper output. Do not use raw email, phone, or legal name by default.
agent_idstringyes for inline authorizationsOpaque agent/workflow ID. Omit when using bundle_id.
bundle_idstringyes for bundle flowReusable agent scope bundle. If present, omit agent_id and scopes.
scopesarrayyes for inline authorizationsArray of { name, constraints? } scope entries.
requires_confirm_forstring arraynoScope names that should return confirm before allowing. Must be included in scopes.
requires_escalation_forstring arraynoPro+ scope names that should return escalate before allowing. Must be included in scopes.
escalation_targetsobjectnoOptional map from scope name to approver label such as manager, security, or compliance.
expires_atRFC 3339 timestampyesAuthorizations must expire; there are no perpetual authorizations.
budget_limit_microsintegernoPro+ authorization-level spend cap in micro-USD. See Budget Gate.
metadataobjectnoOpaque data copied into the authorization receipt context.

Budget attribute

budget_limit_micros is a Pro+ authorization attribute. It is not a decision verb.

When an authorization has a budget cap, each budgeted /check call includes estimated_cost_micros. Allowly compares the estimated action cost to the remaining authorization budget before the action runs:

  • under budget: the check continues to the normal decision path (allow, confirm, or escalate)
  • over budget: the check returns deny with reason: "budget_exceeded"
  • every evaluated budget result is recorded in the signed receipt context

Use budget for estimated agent action cost, such as model calls, paid APIs, enrichment jobs, or tool usage. See Budget Gate for request and response examples.

Scope attributes and constraints

Each scope entry has a name and optional constraints.

{
  "name": "email.send",
  "constraints": {
    "max_per_day": 5,
    "resource_pattern": "gmail:thread:*",
    "allowed_initiators": ["user"]
  }
}
ConstraintTypeEffect
max_per_dayintegerAllows only this many successful allow decisions per UTC day for this authorization + scope. Denied and confirm responses do not consume the counter.
resource_patternstringRequires /v1/check.resource to match this fnmatch-style pattern. Mismatch returns deny / scope_not_authorized.
allowed_initiatorsstring arrayRequires /v1/check.context.initiated_by to be one of these values. Mismatch returns deny / scope_not_authorized.

Constraints are evaluated only after the authorization exists, is active, and includes the requested scope.

Check request attributes

Send these to /v1/check.

AttributeTypeRequiredNotes
authorization_idstringyesStored ID from POST /v1/authorizations.
scopesstring arrayyesOne or more scope names. Response is keyed by scope name. Duplicate scopes are rejected.
resourcestring or nullnoResource identifier such as gmail:thread:abc. Used by resource_pattern and tombstones.
session_idstring or nullnoCustomer session label copied into the signed receipt context.
contextobjectnoOpaque runtime facts. context.initiated_by is used by allowed_initiators.
estimated_cost_microsintegerrequired for budgeted authorizationsEstimated cost in micro-USD. Launch budget checks support exactly one scope.

user_id and agent_id are not accepted in /v1/check; Allowly looks them up from the authorization to avoid spoofing.

Check result attributes

Each result in the results map can include:

AttributeTypeWhen present
decisionstringAlways.
reasonstringAlways.
receiptobjectAlways. Pending by default, signed if ?wait=true completes in time.
budgetobjectWhen budget was evaluated.
confirm_noncestringOnly when decision is confirm.
confirm_expires_atRFC 3339 timestampOnly when decision is confirm.
confirm_prompt_hintstringOnly when decision is confirm.
escalationobjectOnly when decision is escalate. Contains escalation ID, status, target, and expiry.
escalation_idstringOnly when decision is escalate.
escalation_tostringOnly when decision is escalate and a target was configured.
escalation_expires_atRFC 3339 timestampOnly when decision is escalate.

SDK-local fallback results add SDK fields such as is_fallback / isFallback and fallback_mode / fallbackMode. A fallback result has no signed Allowly receipt because Allowly did not make that decision.

Evaluation order

For each requested scope, Allowly evaluates:

  1. Authorization exists.
  2. Authorization is not revoked.
  3. Authorization is not expired.
  4. Scope is included in the authorization.
  5. Scope constraints match resource and context.
  6. Resource is not tombstoned.
  7. Rate limit is not exceeded.
  8. Budget cap is not exceeded.
  9. Escalation approval is active, or escalate is returned for scopes that require escalation.
  10. Confirmation is active, or confirm is returned for scopes that require confirmation.
  11. Otherwise, return allow.