Skip to content
OpenAppPhysical access, simplified
Login

Require step-up

Type
require_step_up
Category
Agent safety
Enforced at
Access-time
Tiers
OrgIntegration
Enforcement
Enforce
Default
Not configured — no extra confirmation beyond ordinary authorization.

Requires an extra confirmation step before a physical write (for example opening a door) for the listed principal kinds. Human admins are not included unless applies_to says so. Use this so an agent or API key cannot move hardware on a single unattended call.

When it is enforced

Evaluated when someone opens a door or gate or triggers an entity action. If this policy applies, the open is denied even when roles and grants would otherwise allow it.

Where to set it

Settings → Policies (org) or the integration Policies tab.

Policies never grant access. See thepolicies architecture guidefor how org, integration, and device tiers combine.

Arguments

The config object on create/update. Shared row fieldsenforcement (enforce, require_approval,audit_only) and enabled apply to every type;audit_only and disabled rows never block.

NameTypeRequiredValuesDescription
applies_tostring or string[]No
agentapi_keyinvitationmemberresidentadminall
Principal kinds this row binds. Closed set: agent, api_key, invitation, member, resident, admin, all. Unknown strings and empty arrays are rejected. `all` matches every kind. When omitted, the type-specific default applies (see Default). Device-tier rows without `applies_to` often bind everyone, including admins. Default: agent, api_key, invitation
outputstring or integerNoOptional channel or output id. When set, the policy binds only that output. When omitted, it binds every output of the tier target. A scoped row does not apply when the acting output is unknown.

How overlapping rows combine

Boolean OR across applicable enforcing rows (any require-step-up wins).

Example

An API key must send the extra confirmation header before switchable.open succeeds. A resident opening from the portal is unaffected.

config
{
"applies_to": [
"agent",
"api_key"
]
}

Integrations

This type is documented on these connectors:

The generated OpenAPI document exposes the config object as RequireStepUpPolicyConfig. applies_to accepts one principal kind or an array of principal kinds; the array form is canonical for generated clients. output is optional and accepts a provider-derived channel or output id (string or integer).

{
"applies_to": ["agent", "api_key"],
"output": "main"
}

Unknown or empty principal selectors are rejected. Omit applies_to to use the policy’s default principal set, or omit output to apply it to every output of the tier target.

require_step_up currently uses the authenticated preview-confirmation protocol. It is an additional confirmation of the exact write request, not an independent second factor or a replacement for MFA.

  1. Call POST /entities/{id}/actions/{action_id}/preview with the exact JSON payload that will be executed.
  2. If confirmation is required, the response includes preview_token.
  3. Repeat the same request at POST /entities/{id}/actions/{action_id} with the token in X-OpenApp-Confirm.

The token is short-lived (10 minutes), single-use, and bound to the organization, authenticated principal, entity, action id, and exact JSON payload. A missing, expired, replayed, cross-principal, cross-entity, cross-action, or payload-mismatched token is rejected. A boolean header or a random ULID is not a valid proof. The preview does not call the hardware provider; the execute request is the only call that performs the physical write.

The proof is issued only after ordinary authentication and authorization succeed. Deployments that require a separate second factor must enforce that requirement in their authentication or credential layer; this policy does not claim to provide MFA.