Access API
Set the server's access policies and connector grants. Use these rules to restrict which capabilities and API operations a principal may use.
Operations
admitAccess
POST /api/v2/access/admit
Requires: invoke role, worker role
Like evaluate but consumes at most one token per matching rate rule when allowed. This is for additional gateway operations: invocation admission is already charged centrally inside traversers.submit, so do not call it for submissions (they would be charged twice). retry_after_ms is set only for rate_limited.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.admit_access()
Request body
AccessAdmission (required)
{
"operation": "string"
}
Responses
Example response 200
{
"allowed": false,
"budget_ids": [
"string"
],
"policy_ids": [
"string"
],
"reason": "bearer_authorization",
"retry_after_ms": 0,
"warnings": [
{
"action": "string",
"as_of": 0,
"budget_id": "string",
"consumed": 0.0,
"enabled": false,
"exceeded": false,
"limit": 0.0,
"metric": "tokens",
"name": "string",
"remaining": 0.0,
"scope": "string",
"subject": "string",
"window": "string",
"window_start": 0
}
]
}
getOwnConnector
GET /api/v2/access/connector
Requires: invoke role, worker role
The caller's connector binding, so a restricted principal can learn its own grants. 404 connector_not_found when the principal is not bound.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.get_own_connector()
Responses
Example response 200
{
"enabled": false,
"expires_at": 0,
"grants": [
"string"
],
"principal": "string",
"revision": 0,
"revoked_at": 0,
"updated_at": 0
}
listConnectors
GET /api/v2/access/connectors
Requires: admin role
Every connector binding in the namespace, ordered by principal.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.list_connectors()
Responses
Example response 200
{
"items": [
{
"enabled": false,
"expires_at": 0,
"grants": [
"string"
],
"principal": "string",
"revision": 0,
"revoked_at": 0,
"updated_at": 0
}
]
}
getConnector
GET /api/v2/access/connectors/{principal}
Requires: invoke role
One principal's connector binding. Non-admins may only read their own (404 otherwise).
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.get_connector()
Parameters
| Parameter | In | Required | Type |
|---|
principal | path | yes | string |
Responses
Example response 200
{
"enabled": false,
"expires_at": 0,
"grants": [
"string"
],
"principal": "string",
"revision": 0,
"revoked_at": 0,
"updated_at": 0
}
putConnector
PUT /api/v2/access/connectors/{principal}
Requires: admin role
Bind an authenticated principal to an allow-list of operation patterns (exact names or `prefix*`, at most 128). Create with expected_revision absent or 0; replace with the current revision (409 revision_conflict otherwise). Grants restrict existing roles and never add any; Store::call rejects ungranted operations with 403 connector_forbidden while the connector's own read, evaluate and admit stay reachable.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.put_connector()
Parameters
| Parameter | In | Required | Type |
|---|
principal | path | yes | string |
Request body
AccessConnectorPut (required)
{
"grants": [
"string"
]
}
Responses
Example response 200
{
"enabled": false,
"expires_at": 0,
"grants": [
"string"
],
"principal": "string",
"revision": 0,
"revoked_at": 0,
"updated_at": 0
}
revokeConnector
POST /api/v2/access/connectors/{principal}/revoke
Requires: admin role
Disable a connector and record revoked_at permanently; a revoked connector never becomes an unrestricted ordinary principal again. Requires the current expected_revision.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.revoke_connector()
Parameters
| Parameter | In | Required | Type |
|---|
principal | path | yes | string |
Request body
AccessConnectorRevoke (required)
{
"expected_revision": 0
}
Responses
Example response 200
{
"enabled": false,
"expires_at": 0,
"grants": [
"string"
],
"principal": "string",
"revision": 0,
"revoked_at": 0,
"updated_at": 0
}
evaluateAccess
POST /api/v2/access/evaluate
Requires: invoke role, worker role
Preview the decision for the authenticated caller without consuming rate tokens. target is `label.capability`; input is matched against constraints. Workers pass task_id/step_id + lease_token to be evaluated as the leased effective principal. Denials are 200 decisions, not errors.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.evaluate_access()
Request body
AccessAdmission (required)
{
"operation": "string"
}
Responses
Example response 200
{
"allowed": false,
"budget_ids": [
"string"
],
"policy_ids": [
"string"
],
"reason": "bearer_authorization",
"retry_after_ms": 0,
"warnings": [
{
"action": "string",
"as_of": 0,
"budget_id": "string",
"consumed": 0.0,
"enabled": false,
"exceeded": false,
"limit": 0.0,
"metric": "tokens",
"name": "string",
"remaining": 0.0,
"scope": "string",
"subject": "string",
"window": "string",
"window_start": 0
}
]
}
listAccessPolicies
GET /api/v2/access/policies
Requires: invoke role
Policies visible to the caller: every namespace policy for admins, otherwise the caller's own. Optional label filter.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.list_access_policies()
Parameters
| Parameter | In | Required | Type |
|---|
label | query | no | string |
Responses
Example response 200
{
"items": [
{
"capability": "string",
"constraints": {
"key": {
"operator": "string",
"value": {}
}
},
"created_at": 0,
"effect": "allow",
"enabled": false,
"expires_at": 0,
"id": "string",
"label": "string",
"name": "string",
"owner": "string",
"principal": "string",
"rate": {
"burst": 0,
"requests_per_second": 0.0
},
"revision": 0,
"tags": [
"string"
],
"updated_at": 0
}
]
}
createAccessPolicy
POST /api/v2/access/policies
Requires: invoke role
Create a durable admission policy for one exact node label the caller registered, or `*` for admins. principal and capability accept exact values or a single trailing `*`; embedded wildcards are rejected (400 invalid_access_policy). A matching deny, a violated constraint on a matching allow, or an exhausted rate bucket denies the invocation centrally inside traversers.submit with 403 policy_denied / constraint_denied or 429 rate_limited. No match preserves ordinary bearer authorization; allow rules never grant roles. Namespaces hold at most 1024 policies.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.create_access_policy()
Request body
AccessPolicyCreate (required)
{
"label": "string"
}
Responses
Example response 201
{
"capability": "string",
"constraints": {
"key": {
"operator": "string",
"value": {}
}
},
"created_at": 0,
"effect": "allow",
"enabled": false,
"expires_at": 0,
"id": "string",
"label": "string",
"name": "string",
"owner": "string",
"principal": "string",
"rate": {
"burst": 0,
"requests_per_second": 0.0
},
"revision": 0,
"tags": [
"string"
],
"updated_at": 0
}
getAccessPolicy
GET /api/v2/access/policies/{id}
Requires: invoke role
Read one policy; a policy owned by another principal is 404 policy_not_found rather than 403.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.get_access_policy()
Parameters
| Parameter | In | Required | Type |
|---|
id | path | yes | string |
Responses
Example response 200
{
"capability": "string",
"constraints": {
"key": {
"operator": "string",
"value": {}
}
},
"created_at": 0,
"effect": "allow",
"enabled": false,
"expires_at": 0,
"id": "string",
"label": "string",
"name": "string",
"owner": "string",
"principal": "string",
"rate": {
"burst": 0,
"requests_per_second": 0.0
},
"revision": 0,
"tags": [
"string"
],
"updated_at": 0
}
updateAccessPolicy
PATCH /api/v2/access/policies/{id}
Requires: invoke role
Compare-and-set edit of the mutable fields (principal, capability, effect, name, enabled, expires_at, constraints, rate). label is immutable and unknown keys are rejected. expected_revision must equal the current revision or the request fails with 409 revision_conflict. Spent rate tokens survive edits.
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.update_access_policy()
Parameters
| Parameter | In | Required | Type |
|---|
id | path | yes | string |
Request body
AccessPolicyUpdate (required)
{
"expected_revision": 0
}
Responses
Example response 200
{
"capability": "string",
"constraints": {
"key": {
"operator": "string",
"value": {}
}
},
"created_at": 0,
"effect": "allow",
"enabled": false,
"expires_at": 0,
"id": "string",
"label": "string",
"name": "string",
"owner": "string",
"principal": "string",
"rate": {
"burst": 0,
"requests_per_second": 0.0
},
"revision": 0,
"tags": [
"string"
],
"updated_at": 0
}
deleteAccessPolicy
DELETE /api/v2/access/policies/{id}
Requires: invoke role
Delete one policy and its rate buckets. expected_revision travels as a query parameter and must match (409 revision_conflict).
Generated Python client internals: atfgraph._generated.api.access_api.AccessApi.delete_access_policy()
Parameters
| Parameter | In | Required | Type |
|---|
id | path | yes | string |
expected_revision | query | yes | integer |
Responses
Example response 200
{
"deleted": false,
"id": "string"
}