API7 Docs

Create Guardrail

POST /environments/{env_id}/guardrails

POST /environments/{env_id}/guardrails

Interactive request editor loads with JavaScript.

Authorization

BearerAdminToken
AuthorizationBearer <token>

Organization-scoped admin token. Read operations require a valid token, and write operations require a token with write permission.

In: header

Path Parameters

env_id*string

Environment ID that scopes the request.

Formatuuid

Request Body

application/json

Create-guardrail body. config is validated per-kind by the server; unknown top-level fields are tolerated (see the Guardrails note above).

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "$AISIX_CP/environments/$ENV_ID/guardrails" \  -H "Authorization: Bearer $AISIX_TOKEN" \  -H "Content-Type: application/json" \  -d '{    "name": "Block exposed access keys",    "kind": "keyword",    "hook_point": "input",    "enforcement_mode": "block",    "enabled": true,    "config": {      "patterns": [        {          "kind": "literal",          "value": "AKIA"        }      ]    }  }'

Created

{
  "guardrail": {
    "id": "eb6a639d-2b4e-4f80-a24d-65a96ac30603",
    "env_id": "6fbea7f2-88a7-4cbb-8dca-a0ad785d07c5",
    "name": "Block exposed access keys",
    "enabled": true,
    "hook_point": "input",
    "kind": "keyword",
    "fail_open": false,
    "config": {
      "patterns": [
        {
          "kind": "literal",
          "value": "AKIA"
        }
      ]
    },
    "family": "regex_rule",
    "provider": "builtin",
    "check_type": "content_moderation",
    "enforcement_mode": "block",
    "direction": "both",
    "created_at": "2026-07-31T09:20:00Z",
    "updated_at": "2026-07-31T09:20:00Z"
  }
}
Complete operation details and schema variants

POST /environments/{env_id}/guardrails

Create Guardrail

Create a guardrail in an environment. The per-kind config shape is validated by the server against the guardrail catalog (GET /guardrails/schema); this spec models the stable envelope and treats config as an open object.

Parameters

  • env_id (path, string, required): Environment ID that scopes the request.

Request body

Content type: application/json

  • name (string, required): Human-readable guardrail name, unique within the environment.

  • enabled (boolean, optional): Whether connected gateways evaluate the guardrail. Omit to create it enabled.

  • hook_point (string, optional): Where in the request lifecycle the guardrail executes. This is the runtime control; direction is only metadata.

  • kind (string, required): Guardrail provider kind. Fixed at creation.

  • fail_open (boolean, optional): Whether a provider failure allows the request to continue. Omit to use the server default of false: a guardrail that could not run does not release the request. Send true to prefer availability over enforcement. Note this governs the INPUT hook only; the output hook has its own output_fail_open, which also defaults to false.

  • config (object, optional): Kind-specific configuration validated against the guardrail catalog. Secret values are encrypted before storage.

The read-only projections a GET returns inside config (api_key_set, access_key_secret_set, aws_credentials.secret_set, secret_names) may be sent back here. They are accepted when they match what the request stores and rejected when they do not; they never write anything themselves.

kind: piicustom_patterns[].replacement. Two rules decide what a masked span becomes, and both are easy to guess wrong:

  • The text is used literally. $1 and other group references are not expanded — unlike proxy.url_rewrites elsewhere in this product, which does expand them.
  • If the regex declares at least one capture group, only group 1 of each match is replaced; the rest of the match is kept verbatim. A regex with no capture group replaces the whole match.

Together they make a plausible-looking rule produce a plausible-looking wrong answer: regex: "ACCT-([0-9]{4})-([0-9]{4})" with replacement: "ACCT-$1-****" rewrites ACCT-1234-5678 to ACCT-ACCT-$1-****-5678 — accepted, and still shaped like something redacted. To keep surrounding text, leave it outside the capture group rather than repeating it in the replacement.

Omit replacement for the default [<NAME>_REDACTED] token; an empty string deletes the span.

  • family (string, optional): Guardrail family metadata. Omit family, provider, and check_type together to derive the canonical triple from kind.

  • provider (string, optional): Provider portion of the guardrail metadata triple.

  • check_type (string, optional): Check-type portion of the guardrail metadata triple.

  • enforcement_mode (string, optional): Whether matching content is only observed or actively enforced.

  • direction (string, optional): Input/output classification hint stored with the guardrail. Guardrail execution still follows hook_point; changing this value does not move evaluation to a different lifecycle hook.

Responses

  • 201: Created
  • guardrail (object, required): A configured guardrail as returned by the API.

A guardrail inspects traffic only where an attachment puts it. Creating one attaches it to nothing, so it is enforced nowhere until you POST a guardrail attachment naming its scope; the console does this for you when you pick a scope on the create form. An enabled guardrail with no attachment is a valid state — its scope target may have been deleted — and the gateway treats it as inspecting no traffic rather than as applying everywhere.

  • guardrail.id (string, required): Guardrail ID within the environment.

  • guardrail.env_id (string, required): Environment that owns the guardrail.

  • guardrail.name (string, required): Human-readable guardrail name, unique within the environment.

  • guardrail.enabled (boolean, required): Whether connected gateways evaluate this guardrail.

  • guardrail.hook_point (string, optional): Where in the request lifecycle the guardrail executes. This is the runtime control; direction is only metadata.

  • guardrail.kind (string, required): Guardrail provider kind. Fixed at creation.

  • guardrail.fail_open (boolean, optional): When the remote guardrail provider cannot complete its check, allow (true) or block (false) the request. Defaults to false — an unchecked request is not released. No-op for kind=keyword.

  • guardrail.config (object, optional): Kind-specific configuration. Shape is validated server-side against the guardrail catalog; secrets are redacted here.

Kinds that store a secret replace it with a server-computed summary of what is held: api_key_set, access_key_secret_set, aws_credentials.secret_set or secret_names. These are read-only projections. You may send them straight back on create or update — the value is accepted when it matches what the server holds, so a read-modify-write round-trip works unchanged — but they never write anything: a value that disagrees is rejected with 400 rather than silently ignored. To change the underlying secret, send the secret field itself (api_key, access_key_secret, aws_credentials.secret_access_key, or secrets).

  • guardrail.family (string, optional): Dashboard grouping metadata (not sent to the data plane).

  • guardrail.provider (string, optional): Provider metadata used to select the guardrail configuration form.

  • guardrail.check_type (string, optional): Check-category metadata used to select the guardrail configuration form.

  • guardrail.enforcement_mode (string, optional): Whether matching content is only observed or actively enforced.

  • guardrail.direction (string, optional): Input/output classification hint stored with the guardrail. Guardrail execution still follows hook_point; changing this value does not move evaluation to a different lifecycle hook.

  • guardrail.created_at (string, optional): RFC3339 time when the guardrail was created.

  • guardrail.updated_at (string, optional): RFC3339 time when the guardrail was last updated.

  • warnings (array, optional): Present on create and update when some data plane nodes in the environment run a gateway version that will not execute part of the saved configuration — a custom pattern replacement, for example, makes an older gateway drop the whole guardrail, which then stops enforcing there entirely. Never present on reads.

  • warnings[].code (string, required): How affected nodes treat the saved resource. field_ignored: the resource stays in service on those nodes but the named field has no effect there — beware when the field is restrictive, since the restriction is silently not enforced. row_rejected: those nodes refuse the whole resource, so it stops serving there entirely (or, if a previously accepted version exists, they keep serving the old values).

  • warnings[].field (string, required): Dot-separated path of the field that triggered the warning, as delivered to gateway nodes.

  • warnings[].min_dp_version (string, required): Oldest gateway version that fully executes the field. The literal value unreleased means no released gateway version executes it yet.

  • warnings[].affected_dp_count (integer, required): Number of currently registered nodes in the environment running an older gateway version than min_dp_version.

  • warnings[].affected_dp_versions (array, required): Distinct gateway versions reported by the affected nodes, capped at five entries. Nodes that report no version appear as unknown.

  • 400: Request body or parameters failed validation.

  • error (object, required): Error details.

  • error.code (string, required): Machine-readable identifier. Examples: UNAUTHENTICATED, INVALID_REQUEST, MASTER_KEY_UNSET, INTERNAL.

  • error.message (string, required): Human-readable explanation; safe to surface to operators.

  • 401: Missing or invalid bearer. Response fields (application/json): identical to POST /environments/{env_id}/guardrails, response 400 above.

  • 403: Authenticated request is not permitted. Response fields (application/json): identical to POST /environments/{env_id}/guardrails, response 400 above.

  • 404: Resource not found. Response fields (application/json): identical to POST /environments/{env_id}/guardrails, response 400 above.

  • 409: Request conflicts with current resource state. Response fields (application/json): identical to POST /environments/{env_id}/guardrails, response 400 above.

cURL

curl -X POST '$AISIX_CP/environments/{env_id}/guardrails' -H 'Authorization: Bearer $AISIX_TOKEN'