Add a policy in the dashboard
- Open the app and click Policies in the sidebar.
- Click Add Policy and pick a type: Key Auth, Rate Limit, Firewall, OpenAPI Validation, or Logging.
- Pick the environment. The default, All Environments, adds the same policy to both production and preview.
- Add match conditions if the policy should only apply to some requests.
- Save, then redeploy.

Set policies with the API
Each endpoint takes theproject, app, and environment by ID or slug.
gateway.listPoliciesreturns the list in the order it runs, with IDs.gateway.setPoliciesreplaces the whole list with thepoliciesarray you send, in that order. If any policy is invalid, nothing is saved. An empty array removes every policy. Every policy gets a new ID.gateway.updatePolicychanges one policy bypolicyId. Fields you leave out keep their values, andmatch: nullremoves all match expressions. Sending one ofkeyauth,ratelimit,firewall,openapi, orloggingreplaces the rule and can change its type.
environment.*.set_policies to replace the list, environment.*.read_policies to list, and environment.*.update_policy to change one, or the same actions on environment.<environment_id>.…. See root key permissions. A keyspace in an authentication policy must be in the same workspace, or the call fails with err:unkey:data:key_space_not_found.
Every change, from the dashboard, API, or CLI, is recorded in the audit log with the full policy list.
Set policies with the CLI
unkey api gateway list-policies, set-policies, and update-policy do the same as the three endpoints. Each takes --project, --app, and --environment. set-policies takes the full list as --policies '<json array>', and update-policy takes --policy-id and --policy '<json object>'.
What’s in a policy
string
required
Shown in the dashboard. 1 to 256 characters.
boolean
required
A turned-off policy is kept but skipped.
MatchExpr[]
Up to 10 expressions. A request must match all of them for the policy to apply. Leave it out to apply the policy to every request.
object
required
Set exactly one. It picks the policy type and holds its settings. See API key authentication, Rate limit, Firewall, OpenAPI validation, and Logging.
id. It changes every time gateway.setPolicies replaces the list.
Pick which requests a policy applies to
Each match expression sets exactly one ofpath, method, header, or queryParam. A request must match every expression in the policy. To match one thing or another, create two policies.
StringMatch
Matches the request path. Set exactly one of
exact, prefix, or regex (1 to 1024 characters), and optionally ignoreCase: true. Regular expressions use RE2 syntax, and one that doesn’t compile is rejected when you save.string[]
One or more of
GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Matches any of them, ignoring case.FieldMatch
name (1 to 256 characters) plus exactly one of present: true or value (a StringMatch like path). With value, it matches if any value of that header matches.FieldMatch
Same as
header, for a query parameter. Names are case-sensitive.Example: block POST and DELETE on internal paths
Put policies in the right order
The gateway runs every enabled policy that matches, from top to bottom. Order matters in three ways:- Authentication first. The first API key policy that succeeds decides who the caller is. Later API key policies are skipped.
- Rate limits by caller go after authentication. A rate limit that counts by
authenticatedSubjectorprincipalFieldneeds to know the caller. If it runs first, every request counts asunknown. - A rejection stops everything. After a firewall block, a failed key check, a used-up rate limit, or an OpenAPI error, no later policy runs, including logging.
Limits
- 50 policies per environment.
- 10 match expressions per policy.
- 5 keyspaces and 10 key rate limits per API key policy.
- 5 identifiers per rate limit policy.
- Match strings up to 1024 characters, and names up to 256.
Next steps
API key authentication policy
Verify Unkey keys and forward the principal.
Rate limit policy
Limit by IP, header, path, subject, or principal field.
Firewall policy
Deny the requests your match expressions select.
Logging policy
Capture headers, query data, and bodies for matched requests.