Skip to content

Access control

Upsert Access Control Rule

View source specification ↗
POST /access-control-rules

Upsert Access Control Rule

Requires a signed user/session or the existing authenticated client flow. The anonymous DCR delegated device profile cannot invoke this operation.

Required scope

Any authenticated access token

Header parameters

Idempotency-KeystringRequired

Client-chosen key that makes a non-idempotent request retry-safe, following draft-ietf-httpapi-idempotency-key-header. A committed response is stored for 24 hours and replayed for the same principal, operation, key and payload. Missing key returns 400 IDEMPOTENCY_KEY_REQUIRED, a key longer than 255 characters returns 400 IDEMPOTENCY_KEY_INVALID, the same key with a different payload returns 422, and the same key while the first request is still in flight returns 409. Requests rolled back before external provider attempts do not consume the key. Group mutations retain terminal failed responses after provider attempts together with received provider truth; their operation contract defines these replayable outcomes.

minLength: 1

maxLength: 255

If-Matchstring

Required for a full replacement when the request identifies an existing resource. Send that resource's quoted strong etag from its last GET. A missing condition on a replacement returns 428 PRECONDITION_REQUIRED; a stale condition returns 412 PRECONDITION_FAILED. Omit this header when creating a new resource without an id. Wildcards are accepted only where the operation explicitly permits them.

minLength: 1

Request body

Required

Fields

idstring

The ID of the access control rule to upsert on.

minLength: 1

effectstringRequired

Allowed values

  • ALLOW
  • DENY
operationstringRequired

The operation to grant access to. This could be a read, write, delete, etc. Please see the access controls list specification for all operations and their descriptions.

resourcestringRequired

The resource to grant access to. This could be an endpoint, a flow, a secret, etc. You can define this as either a class of resources, or a specific resource. Examples: - port1/principals/alice/endpoints/thermostat-zero grants access to that thermostat - port1/principals/alice/flows/* grants access to all flows owned by alice

identitystringRequired

The identity to grant access to. This could be a user, a role, a group, etc. You can define this as either a class of identities, or a specific identity. Examples: - port1/principals/bob grants access to bob - * just grants access to all identities

conditionsarray<AccessControlRuleCondition>

Conditions on the operation context that must all match for the rule to apply. Omitting conditions means the rule has none.

A condition that must hold on the operation context for the rule to apply. A rule applies only when all of its conditions match.

keystringRequired

The operation-context attribute a rule condition compares against.

Allowed values

  • AUTH_VARIANT
  • REGIONALIZATION
  • TARGET_OPERATION
  • TARGET_IDENTITY_KIND
comparatorstringRequired

How a rule condition compares the context attribute with its value.

Allowed values

  • EQUALS
valuestringRequired

The value the context attribute is compared with.

minLength: 1

maxLength: 200

reasonstring

Optional operator-supplied reason recorded in the audit log for this change.

maxLength: 500

Returns

200

Access control rule upserted successfully

Fields
idstringRequired

The ID of the access control rule

effectstringRequired

Allowed values

  • ALLOW
  • DENY
operationstringRequired

The operation that the identity is granted to perform on a resource. A Universal resource identifier namespaced under port1/systems/zero/operations/

resourcestringRequired

The resource permissions are granted to

identitystringRequired

The identity permissions are granted to

ownerstringRequired

The owner of the access control rule

conditionsarray<AccessControlRuleCondition>Required

Conditions on the operation context that must all match for the rule to apply. Always returned, possibly empty.

A condition that must hold on the operation context for the rule to apply. A rule applies only when all of its conditions match.

keystringRequired

The operation-context attribute a rule condition compares against.

Allowed values

  • AUTH_VARIANT
  • REGIONALIZATION
  • TARGET_OPERATION
  • TARGET_IDENTITY_KIND
comparatorstringRequired

How a rule condition compares the context attribute with its value.

Allowed values

  • EQUALS
valuestringRequired

The value the context attribute is compared with.

minLength: 1

maxLength: 200

etagstringRequired

The quoted strong entity tag of the access control rule, for If-Match

readOnly: true

Response headers
ETagstring

Opaque strong entity tag of the returned resource version. Send it back in `If-Match` on the next mutation of the same resource.

Errors

400

Invalid request payload

Check the request fields and any validation details, then correct the payload.

401 UNAUTHORIZED

Authentication is required

Obtain a valid access token, then retry.

403 FORBIDDEN

The caller may not perform this action

Check the linked account and its permissions for the device or resource.

404 NOT_FOUND

The named resource does not exist

Verify the target identifier and that its endpoint or plugin route still exists.

409 IDEMPOTENCY_KEY_IN_FLIGHT

A request with this idempotency key is in flight

Check the device’s current mode or state. Retry only after the conflict is resolved.

412 PRECONDITION_FAILED

The If-Match etag does not match the current access control rule; re-read the rule and retry

Inspect the returned code and family and follow the error handling guide.

422 IDEMPOTENCY_KEY_REUSED

The idempotency key was already used with another payload

Correct the rejected value using the constraints in the error details or request schema.

428 PRECONDITION_REQUIRED

If-Match is required for a replacement or deletion

Inspect the returned code and family and follow the error handling guide.

500 INTERNAL

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Get Access Control Rules

View source specification ↗
GET /access-control-rules

Get access-control rules owned by the authenticated caller by default. Supplying an owner selects that owner's rules, and an ID selects one rule; results remain subject to the caller's access-control-rule-read permissions. The default page size is 10 and the maximum page size is 100.

Requires a signed user/session or the existing authenticated client flow. The anonymous DCR delegated device profile cannot invoke this operation.

Required scope

Any authenticated access token

Query parameters

ownerstring

Owner whose access-control rules to get. Defaults to the authenticated caller unless an ID is supplied. A different owner requires read permission for each returned rule.

idstring

Exact access-control rule identifier to retrieve. The result is included only when the caller has read permission.

operationstring

Exact operation to match. Only rules whose operation equals this value are returned.

resourcestring

Exact resource to match. Only rules whose resource equals this value are returned.

identitystring

Exact identity to match. Only rules whose identity equals this value are returned.

nextTokenstring

Opaque token for the next page of results. Pass the continuation token returned by the previous response, unchanged. Omit it to start from the first page.

maxResultsinteger

Maximum number of results to return in one page. Defaults to 100. Values from 1 through 100 are accepted.

minimum: 1

maximum: 100

Default: 100

expandarray<string>

Expansion tokens that request related or computed fields for each result. When omitted, the response contains only the default, shallower set of fields for each result.

Returns

200

Access control rules retrieved successfully

Fields
resultsarray<AccessControlRule>Required
idstringRequired

The ID of the access control rule

effectstringRequired

Allowed values

  • ALLOW
  • DENY
operationstringRequired

The operation that the identity is granted to perform on a resource. A Universal resource identifier namespaced under port1/systems/zero/operations/

resourcestringRequired

The resource permissions are granted to

identitystringRequired

The identity permissions are granted to

ownerstringRequired

The owner of the access control rule

conditionsarray<AccessControlRuleCondition>Required

Conditions on the operation context that must all match for the rule to apply. Always returned, possibly empty.

A condition that must hold on the operation context for the rule to apply. A rule applies only when all of its conditions match.

keystringRequired

The operation-context attribute a rule condition compares against.

Allowed values

  • AUTH_VARIANT
  • REGIONALIZATION
  • TARGET_OPERATION
  • TARGET_IDENTITY_KIND
comparatorstringRequired

How a rule condition compares the context attribute with its value.

Allowed values

  • EQUALS
valuestringRequired

The value the context attribute is compared with.

minLength: 1

maxLength: 200

etagstringRequired

The quoted strong entity tag of the access control rule, for If-Match

readOnly: true

paginationContextPaginationContext
errorsarray<Error>

Partial query errors collected while returning available results.

The one Port OS error shape, returned by every REST error response and every MCP tool error. `code` names the specific failure and `family` its broad class; both are closed enums, so clients branch on them and show `message`, which says what failed and what to do next.

familystringRequired

The broad class of an error. The family decides the HTTP status of a REST error, so clients can handle every code of a family alike.

codestringRequired

The specific error, one of a closed set of Port OS codes. Every REST error body, MCP tool error, batch item error and discovery item error uses this enum; each code belongs to an `ErrorFamily` that decides its HTTP status. Provider-specific codes are never codes: they travel in `details.providerCode`. New failure kinds are added here, never as free strings.

messagestringRequired

Plain-language description of the failure and the suggested next action.

detailsErrorDetails

Optional typed context for an error. Fields are additive and only populated when the error can safely expose that context to API clients.

errorsarray<SynchronizationItemError>

Every rejected item when a request that is validated item by item and applied atomically fails, such as a discovery `SynchronizationRequest` whose routes, group routes or relationships are rejected. Omitted for single-item failures.

One rejected discovery item of a `SynchronizationRequest`, keyed by the plugin-owned identity of the rejected item: `pluginRouteId` for a route or group route, or `relationshipExternalId` for a relationship. Exactly one of the two is set. It shares the `code`, `family`, `status` and `message` fields of `BatchItemError`; discovery items are keyed by plugin-owned identity because they carry no `requestId`. A request with any rejected item is rejected as a whole and lists every rejected item.

pluginRouteIdstring

Plugin-owned identifier of the rejected route or group route. Set unless the item is a relationship.

relationshipExternalIdstring

Plugin-owned `externalId` of the rejected relationship. Set only for relationship items.

interfacestring

Canonical capability interface name the failure applies to, when the failure is interface-specific.

versionstring

Declared capability interface version the failure applies to, when the failure is interface-specific.

codestringRequired

The specific error, one of a closed set of Port OS codes. Every REST error body, MCP tool error, batch item error and discovery item error uses this enum; each code belongs to an `ErrorFamily` that decides its HTTP status. Provider-specific codes are never codes: they travel in `details.providerCode`. New failure kinds are added here, never as free strings.

familystringRequired

The broad class of an error. The family decides the HTTP status of a REST error, so clients can handle every code of a family alike.

statusintegerRequired

HTTP-equivalent status code of the item failure.

minimum: 400

maximum: 599

messagestringRequired

Plain-language description of the failure and the suggested fix.

Response headers
ETagstring

Opaque strong entity tag of the returned resource version. Send it back in `If-Match` on the next mutation of the same resource.

Errors

400 BAD_REQUEST

Invalid owner, ID, page size, or pagination token

Check the request fields and any validation details, then correct the payload.

401 UNAUTHORIZED

Authentication is required

Obtain a valid access token, then retry.

500 INTERNAL

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Get Access Control Rule Audit

View source specification ↗
GET /access-control-rule-audit-entries

Read the audit of access-control rule changes, newest first. Every rule upsert and delete records who made it, through which client, why, and under which request, plus the rule as it was written. Entries hold identifiers and the rule's shape only, never token text. Entries older than the configured retention (auth.audit.retentionDays, default 365) are pruned at server start.

Only operator callers (operational tokens) and system zero may read the audit; any other caller receives 403. The default page size is 50 and the maximum is 200.

Required scope

Any authenticated access token

Query parameters

ruleIdstring

Only entries about this access-control rule.

actorPrincipalstring

Only entries made by this principal.

resourcestring

Exact resource of the audited rule.

operationstring

Exact operation of the audited rule.

sincestring

Only entries recorded at or after this time (RFC 3339).

format: "date-time"

untilstring

Only entries recorded before this time (RFC 3339).

format: "date-time"

nextTokenstring

Opaque token for the next page of results. Pass the continuation token returned by the previous response, unchanged. Omit it to start from the first page.

maxResultsinteger

Maximum number of entries to return in one page. Defaults to 50. Values from 1 through 200 are accepted.

minimum: 1

maximum: 200

Default: 50

Returns

200

Audit entries retrieved successfully

Fields
resultsarray<AccessControlRuleAuditEntry>Required

Audit entries, newest first.

One recorded access-control rule change. Holds identifiers and the rule's shape only, never token text.

idstringRequired

The unique ID of the audit entry.

atstringRequired

When the change was recorded.

format: "date-time"

actorPrincipalstringRequired

The principal that made the change.

actorClientstring

The OAuth client the actor's token was issued to; absent when unknown.

actionstringRequired

What an access-control rule audit entry records. UPSERT: the rule was created or updated. DELETE: the rule was deleted.

Allowed values

  • UPSERT
  • DELETE
ruleIdstringRequired

The access-control rule the change was about.

identitystringRequired

The identity of the rule as it was written.

resourcestringRequired

The resource of the rule as it was written.

operationstringRequired

The operation of the rule as it was written.

conditionsarray<AccessControlRuleCondition>Required

The rule's conditions as written, normalized.

A condition that must hold on the operation context for the rule to apply. A rule applies only when all of its conditions match.

keystringRequired

The operation-context attribute a rule condition compares against.

Allowed values

  • AUTH_VARIANT
  • REGIONALIZATION
  • TARGET_OPERATION
  • TARGET_IDENTITY_KIND
comparatorstringRequired

How a rule condition compares the context attribute with its value.

Allowed values

  • EQUALS
valuestringRequired

The value the context attribute is compared with.

minLength: 1

maxLength: 200

reasonstring

The operator-supplied explanation; absent when none was given.

correlationIdstring

The request ID of the request that made the change; absent for startup work.

resultstringRequired

The outcome an access-control rule audit entry records. COMMITTED: the change was written. UNCHANGED: an upsert matched an existing equivalent rule and wrote nothing.

Allowed values

  • COMMITTED
  • UNCHANGED
paginationContextPaginationContext

Errors

400 BAD_REQUEST

Invalid filter, page size, time or pagination token

Check the request fields and any validation details, then correct the payload.

401 UNAUTHORIZED

Authentication is required

Obtain a valid access token, then retry.

403 FORBIDDEN

The caller is not an operator

Check the linked account and its permissions for the device or resource.

500 INTERNAL

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Evaluate Access Control Rule

View source specification ↗
POST /access-control-rules/evaluate

Evaluate an access control rule.

Requires a signed user/session or the existing authenticated client flow. The anonymous DCR delegated device profile cannot invoke this operation.

Required scope

Any authenticated access token

Request body

Required

Fields

requesterContextAccessControlRequesterContextRequired
resourceContextAccessControlResourceContextRequired
entitiesarray<AccessControlEntity>Required
idstringRequired

The ID of the entity

typestringRequired

The type of the entity

ownerstringRequired

The owner of the entity

contextobject

Additional context for the entity

operationstringRequired
operationContextAccessControlOperationContext

Attributes of the requested operation that rule conditions are evaluated against.

Returns

200

Access control rule evaluated successfully

Fields
resultstring

Allowed values

  • ALLOW
  • DENY
errorError

The one Port OS error shape, returned by every REST error response and every MCP tool error. `code` names the specific failure and `family` its broad class; both are closed enums, so clients branch on them and show `message`, which says what failed and what to do next.

Errors

400

Invalid request payload

Check the request fields and any validation details, then correct the payload.

500

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Delete Access Control Rule

View source specification ↗
DELETE /{namespace}/{principalType}/{principalId}/access-control-rules/{ruleId}

Delete an access control rule.

Requires a signed user/session or the existing authenticated client flow. The anonymous DCR delegated device profile cannot invoke this operation.

Required scope

Any authenticated access token

Path parameters

namespacestringRequired

The namespace of the principal

principalTypestringRequired

The type of principal

principalIdstringRequired

The ID of the principal

ruleIdstringRequired

The ID of the access control rule to delete

Query parameters

reasonstring

Optional operator-supplied reason recorded in the audit log for this deletion.

maxLength: 500

Header parameters

Idempotency-KeystringRequired

Client-chosen key that makes a non-idempotent request retry-safe, following draft-ietf-httpapi-idempotency-key-header. A committed response is stored for 24 hours and replayed for the same principal, operation, key and payload. Missing key returns 400 IDEMPOTENCY_KEY_REQUIRED, a key longer than 255 characters returns 400 IDEMPOTENCY_KEY_INVALID, the same key with a different payload returns 422, and the same key while the first request is still in flight returns 409. Requests rolled back before external provider attempts do not consume the key. Group mutations retain terminal failed responses after provider attempts together with received provider truth; their operation contract defines these replayable outcomes.

minLength: 1

maxLength: 255

If-MatchstringRequired

The quoted strong entity tag of the resource the client last read (its `etag` field or `ETag` response header). The mutation is applied only when it still matches: a stale value returns 412 PRECONDITION_FAILED and a missing header returns 428 PRECONDITION_REQUIRED. Wildcards are accepted only where the operation explicitly permits them.

minLength: 1

Returns

200

Access control rule deleted successfully

No response body.

Errors

400

Invalid request payload

Check the request fields and any validation details, then correct the payload.

401 UNAUTHORIZED

Authentication is required

Obtain a valid access token, then retry.

403 FORBIDDEN

The caller may not perform this action

Check the linked account and its permissions for the device or resource.

404 NOT_FOUND

The named resource does not exist

Verify the target identifier and that its endpoint or plugin route still exists.

409 IDEMPOTENCY_KEY_IN_FLIGHT

A request with this idempotency key is in flight

Check the device’s current mode or state. Retry only after the conflict is resolved.

412 PRECONDITION_FAILED

The If-Match etag does not match the current access control rule; re-read the rule and retry

Inspect the returned code and family and follow the error handling guide.

422 IDEMPOTENCY_KEY_REUSED

The idempotency key was already used with another payload

Correct the rejected value using the constraints in the error details or request schema.

428 PRECONDITION_REQUIRED

If-Match is required for a replacement or deletion

Inspect the returned code and family and follow the error handling guide.

500

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.