Skip to main content

Version: latest

Permission Policies and Boundaries

API7 Gateway implements fine-grained access control through permission policies and permission boundaries. Both are expressed as JSON documents using the same syntax, and both are evaluated at request time to decide whether a given action on a given resource is allowed.

This page documents the exact JSON structure that the Control Plane accepts. For the full catalog of allowed actions and resources, see Permission Policy Actions and Resources. For ready-to-adapt examples, see Permission Policy Examples.

Concepts

  • Permission policy — A JSON document that defines a set of statements. Each statement allows or denies specific actions on specific resources, optionally constrained by conditions. A permission policy can be attached to one or more roles.
  • Permission boundary — A permission policy applied directly to a user. A user's effective permissions are the intersection of their roles' permissions and their permission boundary: an action is allowed only when both the user's roles permit it and the user's boundary permits it. Boundaries are the primary mechanism for safe delegation — for example, giving a team lead the ability to manage users in their own department without letting them escalate privileges.

Policy document structure

A permission policy is created via the Admin API by POSTing a PermissionPolicy object to /api/permission_policies. The top-level object has the following fields:

FieldTypeRequiredDescription
namestringyesHuman-readable name of the policy.
descstringnoDescription of what the policy grants.
labelsmap[string]stringnoLabels attached to the policy itself for organization and filtering.
policy_documentobjectyesThe actual policy rules, wrapped in a policy_document object.

The policy_document object contains a single statement field holding an array of statements:

{
"name": "production-readonly",
"desc": "Read-only access to production gateway groups.",
"labels": {
"team": "sre",
"env": "production"
},
"policy_document": {
"statement": [
{
"effect": "allow",
"resources": [
"arn:api7:gateway:gatewaygroup/<.*>"
],
"actions": [
"<.*>Get<.*>"
],
"conditions": {
"gateway_group_label": {
"type": "MatchLabel",
"options": {
"key": "env",
"operator": "exact_match",
"value": "production"
}
}
}
}
]
}
}

Statement fields

Each entry in policy_document.statement is an object with the following fields:

FieldTypeRequiredDescription
effectstringyesEither "allow" or "deny".
resourcesarray of stringsyesOne or more ARN-style resource patterns this statement applies to. Regular expressions can be embedded inside <...>.
actionsarray of stringsyesOne or more action names this statement applies to. Regular expressions can be embedded inside <...>.
conditionsobjectnoRuntime conditions that further constrain when the statement matches. See Conditions.

Actions

Actions use the form <namespace>:<verb><resource-type>, for example:

  • gateway:GetPublishedService
  • gateway:CreateConsumer
  • gateway:DeleteConsumerCredential
  • iam:InviteUser
  • iam:UpdateRole
  • portal:CreateAPIProduct

Three namespaces are used today: gateway: for data plane configuration, iam: for identity and organization settings, and portal: for Developer Portal resources. The complete catalog is documented in Permission Policy Actions and Resources.

Actions support regex wildcards enclosed in angle brackets:

  • <.*> matches every action.
  • <.*>Get<.*> matches every read-only action across all namespaces.
  • gateway:<.*>CustomPlugin<.*> matches every custom plugin action.

Resources

Resources use an ARN-style format: arn:api7:<namespace>:<resource-type>/<id>[/<sub-resource-type>/<sub-id>].

Examples from each namespace:

NamespaceResource patternApplies to
gatewayarn:api7:gateway:gatewaygroup/<gateway-group-id>A specific gateway group and its top-level resources (certificates, global rules, plugin metadata, etc.)
gatewayarn:api7:gateway:gatewaygroup/<gg-id>/publishedservice/<svc-id>A specific published service inside a gateway group
gatewayarn:api7:gateway:gatewaygroup/<gg-id>/consumer/<username>A specific consumer inside a gateway group
gatewayarn:api7:gateway:servicetemplate/<service-template-id>A specific service template
gatewayarn:api7:gateway:gatewaysetting/*Global gateway settings (custom plugins, deployment settings)
gatewayarn:api7:gateway:alert/<alert-policy-id>A specific alert policy
iamarn:api7:iam:user/<user-id>A specific user
iamarn:api7:iam:role/<role-id>A specific role
iamarn:api7:iam:permissionpolicy/<permission-policy-id>A specific permission policy
iamarn:api7:iam:contactpoint/<contact-point-id>A specific alert contact point
iamarn:api7:iam:organization/*Organization-scoped settings (license, audit logs, SCIM, SMTP)
portalarn:api7:portal:portal/<portal-id>A specific Developer Portal instance
portalarn:api7:portal:portal/<portal-id>/apiproduct/<product-id>A specific API product
portalarn:api7:portal:portal/<portal-id>/developer/<developer-id>A specific developer
portalarn:api7:portal:dcrprovider/*Dynamic Client Registration providers

Like actions, resources support regex wildcards inside <...>. For example:

  • arn:api7:gateway:gatewaygroup/<.*> matches every gateway group.
  • arn:api7:gateway:gatewaygroup/<.*>/consumer/<.*> matches every consumer in every gateway group.
  • arn:api7:iam:user/<.*> matches every user.

The complete list of valid resource patterns for every action is documented in Permission Policy Actions and Resources.

Conditions

The optional conditions field constrains a statement further, typically by requiring the target resource to carry specific labels. Each condition has a user-defined key (shown to auditors in the UI), a type, and options.

The following condition types are supported:

MatchLabel

Matches resources that carry a specific label. This is the recommended way to build policies that scale across many resources.

"conditions": {
"gateway_group_label": {
"type": "MatchLabel",
"options": {
"key": "env",
"operator": "exact_match",
"value": "production"
}
}
}

MatchLabel options:

OptionTypeDescription
keystringThe label key on the target resource.
operatorstringOne of exact_match or contains_string.
valuestringThe label value to compare against.

Common condition keys include gateway_group_label, service_label, and permission_policy_label. The key you choose simply identifies which labelled resource the condition applies to; its value must match the resource type referenced in resources.

AllOfStrings

Requires every string in a list to be present in the context. This is primarily used to enforce permission boundaries by name.

"conditions": {
"permission_boundaries": {
"type": "AllOfStrings",
"options": ["boundary_a", "boundary_b"]
}
}

Effect precedence: deny overrides allow

When multiple statements, policies, or roles apply to the same request, API7 Gateway uses the deny overrides allow principle: if any statement produces a deny for the requested action and resource, the request is blocked, regardless of how many allow statements match it. Use explicit deny statements to protect critical operations (for example, iam:UpdateLicense) even when a user holds an otherwise-broad role.

Permission boundaries

A permission boundary is a permission policy attached directly to a user via the Admin API (PUT /api/users/{user_id}/boundaries). Its purpose is to set the maximum permissions a user can ever have, regardless of the roles they hold.

Consider a developer named John whose role is "Development Team Member" with full access to the test gateway group. If John is later promoted and also assigned the "Test Engineer" role (which includes full access to production), but his permission boundary still limits him to the test gateway group, John will not gain access to production until his boundary is explicitly updated. This makes boundaries an ideal tool for enforcing organizational constraints that must hold even as roles change.

Best practices

  • Prefer label-based conditions over hard-coded resource IDs when managing many resources. Labels scale without policy edits.
  • Use permission boundaries for sensitive users (contractors, delegated administrators) to cap their maximum privileges.
  • Reserve explicit deny statements for a small number of critical actions (license updates, role deletion, credential reads) to defend against accidental over-granting.
  • Apply the principle of least privilege: start narrow, then expand as needed rather than starting broad.
  • Always scope gateway:CreateGatewayGroup and similar creation actions carefully — unbounded creation rights can be used to spawn isolated environments that evade other controls.

Next steps

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation