Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Secret Policies API

Secret policies tell matching proxies how to apply a credential at the egress boundary, so workloads never see the real value. See Credential Proxying for the runtime semantics, and Static Secrets for source backends.

Each policy is either in inject mode (the proxy adds a header or query parameter to matching requests) or replace mode (the proxy swaps a placeholder token in the URL path for the real value). The two modes are mutually exclusive: a policy carries either an inject_config or a replace_config, never both.

Base path: /v1/policies/secrets

The Secret Policy Object

Inject mode:

{
  "id": "spol_01H...",
  "name": "openai-key",
  "active": true,
  "priority": 0,
  "match_tags": ["production"],
  "mode": "inject",
  "rules": [
    { "host": "api.openai.com", "paths": ["/v1/*"], "methods": ["POST"] }
  ],
  "source": { "type": "env", "var": "OPENAI_API_KEY" },
  "inject_config": {
    "header": "Authorization",
    "formatter": "Bearer {{ .Value }}"
  },
  "created_at": "2026-05-08T12:00:00Z",
  "updated_at": "2026-05-08T12:00:00Z"
}

Replace mode:

{
  "id": "spol_01H...",
  "name": "telegram-bot",
  "active": true,
  "priority": 0,
  "match_tags": ["production"],
  "mode": "replace",
  "rules": [
    { "host": "api.telegram.org", "paths": ["/bot*"], "methods": [] }
  ],
  "source": { "type": "env", "var": "TELEGRAM_BOT_TOKEN" },
  "replace_config": { "proxy_value": "PROXY-BOT-TOKEN" },
  "created_at": "2026-05-08T12:00:00Z",
  "updated_at": "2026-05-08T12:00:00Z"
}

Fields

FieldTypeDescription
idstringServer-assigned opaque ID, prefixed with spol_.
namestringURL-safe name, unique within the organization. Must match [a-z0-9]+(-[a-z0-9]+)*.
activebooleanWhen false, the policy is stored but not delivered to proxies. Defaults to true.
priorityintegerTie-breaker when more than one policy applies. Lower wins. Required.
match_tagsstring[]Tags a proxy must carry for the policy to apply. Empty applies to every proxy.
modestring"inject" or "replace".
rulesobject[]Request rules that scope which traffic the credential applies to. Same shape as network policy rules.
sourceobjectWhere the proxy reads the real credential from. See Source object.
inject_configobjectPresent only in inject mode. See Inject config.
replace_configobjectPresent only in replace mode. See Replace config.
created_atstringRFC 3339 timestamp.
updated_atstringRFC 3339 timestamp.

Source Object

The source object tells the proxy where to resolve the real credential at startup. The exact set of fields depends on the source type. See Static Secrets / Secret Sources for the full list of supported backends.

FieldTypeDescription
typestringOne of env, aws_sm, aws_ssm. Defaults to env.
varstringEnvironment variable name. Required when type is env.
secret_idstringAWS Secrets Manager ARN. Required when type is aws_sm.
namestringParameter Store name. Required when type is aws_ssm.
regionstringAWS region override.
json_keystringJSON key to extract from a JSON-encoded secret value.
ttlstringCache TTL like 15m, 1h. Format: digits followed by h, m, or s.
with_decryptionbooleanDecrypt SecureString parameters (Parameter Store only).

Inject Config

Used when mode is "inject". Set either header or query_param, not both.

FieldTypeDescription
headerstringHeader name to set.
query_paramstringQuery parameter name to append.
formatterstringGo template that produces the header value. Receives .Value and a base64 helper. Required for non-trivial header formats.

Replace Config

Used when mode is "replace". The proxy looks for proxy_value in the URL path and replaces it with the resolved secret before forwarding.

FieldTypeDescription
proxy_valuestringURL-safe placeholder that appears in workload requests. Must be alphanumeric, -._~, or %XX escapes. Required.

List Secret Policies

GET /v1/policies/secrets

Returns every secret policy in the calling organization, ordered by priority ascending.

Query Parameters

NameTypeDescription
namestringExact match on policy name.
activebooleanWhen supplied, returns only policies with that active state.
curl https://api.iron.sh/v1/policies/secrets \
  -H "Authorization: Bearer $IRON_API_KEY"

Create a Secret Policy

POST /v1/policies/secrets

Request Body

FieldTypeRequired
namestringYes
priorityintegerYes
modestringYes (inject or replace)
sourceobjectYes
inject_configobjectWhen mode is inject
replace_configobjectWhen mode is replace
activebooleanNo
match_tagsstring[]No
rulesobject[]No

Submitting a payload with both inject_config and replace_config is allowed: the server clears the config that does not match mode. Submit only the one for the mode you set to keep request bodies obvious.

Example: Bearer Token Injection

curl https://api.iron.sh/v1/policies/secrets \
  -H "Authorization: Bearer $IRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "stripe-key",
    "priority": 42,
    "mode": "inject",
    "match_tags": ["production", "payments"],
    "rules": [
      { "host": "api.stripe.com", "paths": ["/v1/*"], "methods": ["POST"] }
    ],
    "source": { "type": "env", "var": "STRIPE_API_KEY" },
    "inject_config": {
      "header": "Authorization",
      "formatter": "Bearer {{ .Value }}"
    }
  }'

Example: Path Token Replacement

curl https://api.iron.sh/v1/policies/secrets \
  -H "Authorization: Bearer $IRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "telegram-bot",
    "priority": 50,
    "mode": "replace",
    "rules": [
      { "host": "api.telegram.org", "paths": ["/bot*"], "methods": [] }
    ],
    "source": { "type": "env", "var": "TELEGRAM_BOT_TOKEN" },
    "replace_config": { "proxy_value": "PROXY-BOT-TOKEN" }
  }'

Returns 201 Created with the new policy in data.

Retrieve a Secret Policy

GET /v1/policies/secrets/:id

Returns 200 OK with the policy in data, or 404 Not Found with code secret_policy_not_found.

Update a Secret Policy

PUT /v1/policies/secrets/:id

GET the policy, modify the fields you want to change, and PUT the full representation back. Send the same fields you would on create. To switch between modes, change mode and supply the matching inject_config or replace_config: the server clears the other config block automatically.

Example: Switch from Inject to Replace

curl -X PUT https://api.iron.sh/v1/policies/secrets/spol_01H... \
  -H "Authorization: Bearer $IRON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "openai-key",
    "priority": 0,
    "active": true,
    "match_tags": ["production"],
    "mode": "replace",
    "rules": [
      { "host": "api.openai.com", "paths": ["/v1/*"], "methods": ["POST"] }
    ],
    "source": { "type": "env", "var": "OPENAI_API_KEY" },
    "replace_config": { "proxy_value": "proxy-openai-token" }
  }'

Delete a Secret Policy

DELETE /v1/policies/secrets/:id

Returns 204 No Content. Connected proxies stop applying the policy within seconds.