# External Rule Server (ERS)

ERS lets the vault call out to a service you operate for a signing decision. Use it when built-in rule conditions are not expressive enough for your requirements.

:::warning\[Advanced: this requires development]
ERS is not a point-and-click feature. You write a rule-server service and deploy it alongside the vault. Plan for engineering time to build, host, and maintain it. Your security team should review the service before it handles production signing decisions.
:::

## When to use ERS

The built-in Signing Policy covers most use cases: approve or deny by user group, key group, amount, asset, destination address, and exchange. Use ERS when your logic cannot be expressed with those conditions. Examples:

* Time-of-day or rate-limit restrictions your internal risk system tracks.
* Custom whitelist or scoring logic maintained in an external database.
* Integration with a third-party compliance or monitoring service.

## How ERS works

When a signing request matches a rule whose action is **External Rule Server**, the vault calls your ERS endpoint over HTTPS and enforces its decision. Your endpoint must be reachable from the Policy Server nodes. Both directions are signed JSON Web Tokens (JWTs), so each side can verify the other.

**Request (vault to your ERS).** The vault sends an HTTPS `POST` whose body is a JWT signed by the vault (ES256). Verify it with the vault's rule-server signing public key, shown on the Signing Policy page (and at `GET /system-info` as `external_rule_server_signing_pubkey`). The claims describe the signing request:

* `action`: the signing operation (for example `sign_ecdsa`, `sign_ed25519`, `sign_hmac_sha256`).
* `request`: the request itself, including `msg` (the raw payload, hex) and `key_name`.
* `extra_data`: additional context (hex).
* `request_id`: a UUID identifying this evaluation.

**Response (your ERS to the vault).** Return a JWT signed with the algorithm you configured (ES256 or RS256), with claims:

* `result`: `approved`, `rejected`, or `retry`.
* `reason`: a human-readable string (required for `rejected`, optional for `retry`). It appears in the audit log.
* `request_id`: echo back the value from the request.

The vault verifies the response signature against the public key you configured in the rule and checks that `request_id` matches.

## Configure an ERS rule

1. Navigate to **Signing Policy** and click **Edit Rules**.
2. Click **Add Rule** and set up any conditions that scope which requests reach your ERS.
3. Set the action to **External Rule Server**.
4. Enter the **ERS URL** (your service's HTTPS endpoint).
5. Enter the **JWT Algorithm** your service signs responses with (ES256 or RS256) and its **Public Key** in PEM format.
6. Click **Add**, then submit the draft with your passkey.

## Failure and fallback

If the vault cannot reach your ERS endpoint after retrying, or if the response signature does not verify, the request is **denied**. There is no automatic fallback to the next rule. Plan for high availability in your ERS deployment; a service outage stops all signing requests that route to it.

Monitor your ERS for errors using the audit log. Signing events include the ERS result and any failure details.
