Access Policy Reference

Field reference. For how to write a policy, see Access Policies.

Fields

name

How the policy is identified in the console and in denial reasons. When a deny refuses a connection, the reason names this policy.

action

allow or deny. Defaults to allow.

Deny is evaluated first and wins over any allow, however specific.

subject

A type and a value:

Type Value holds Matches
user The user’s id That one user
role The role name Every member holding that role
api-key The API key’s id That one automation
all-members Empty Every member of the namespace

An automation is an API key, not a member, so all-members and role never reach one. That is structural rather than a carve-out: there is no membership to match against. Grant an automation deliberately, with an api-key subject.

A connection from someone who is not a member of the namespace is refused before policies are consulted at all.

filter

Which devices the policy covers. Give exactly one of the two forms:

Form Behavior
"all": true Matches every device, including ones enrolled later
"tags": [...] Matches a device carrying any of the listed tags, one to three

A filter with neither, or with both, is refused with 400. “All devices” is always written out, so a policy never reaches every device because its tag list ended up empty.

logins

Which unix logins the policy covers. Exact names, or ["*"] for any login.

A policy granting ["deploy"] does not permit ssh root@…, even on a device the filter matches.

source_ip

A list of CIDRs. A connection matches when the client address falls inside any of them. A bare address is normalized to a host route — /32, or /128 for IPv6.

Empty matches any address. Source IP only narrows a policy that already matched. It never grants on its own, and it is not a substitute for a subject.

An unparsable CIDR or client address causes a deny to fail closed.

require_reauth

Off by default — the identity alone is the norm.

When set, an identity granted access by this policy must confirm out of band, in the browser, before the connection proceeds, even though the key it presented is already an identity.

When several allows match one connection, the strictest requirement wins: required if any matching allow requires it, at the shortest window. Without that, a broad grant with no re-auth would shadow the narrow policy you wrote specifically to protect production.

reauth_period

The freshness window for require_reauth, in seconds. Only meaningful when require_reauth is set.

Re-authentication is demanded only when the identity has not re-authenticated within the window. The freshness belongs to the identity, not to a connection: inside the window, every login with that key goes straight through.

0 or unset means always — the only setting that is genuinely per login.

Between two matching policies, the shorter window wins, and “always” beats any number.

Evaluation order

  1. Not a member of the namespace → refuse.
  2. Every deny: a match refuses; one that cannot be evaluated also refuses.
  3. Every allow: one match is enough. An allow that cannot be evaluated is a non-match. Collect the strictest re-auth across all that matched.
  4. No allow matched → refuse.

Denial reasons

Reason Meaning
user is not a member of the namespace The connecting account does not belong to this namespace
denied by policy "<name>" A deny matched
denied: policy "<name>" could not be evaluated A deny had a source IP it could not parse, and failed closed
no policy grants "<login>" on this device No allow covered this device and login

The starter policy

Every new namespace is seeded with:

Field Value
name Owner access
action allow
subject user = the namespace owner
filter "all": true — all devices
logins ["*"]
source_ip empty — any address

Created when a namespace is born, or when a legacy one is upgraded with no policies.

Where to go next

esc