---
title: "Rate Limiting"
description: "Configure request rate limits and Redis-backed failure backoff for the Enterprise Issuer2 Service."
stack: "Enterprise Stack (commercial) — version 1.1.1"
stack_version: "1.1.1"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/issuer2-service/configurations/rate-limiting
generated: 2026-10-01
---
# Rate Limiting

The Issuer2 Service applies request rate limits to its OID4VCI `token` and `credential` endpoints. These limits protect the authentication and credential issuance flow from automated abuse while still allowing normal wallet issuance traffic.

Rate limiting is configured in the unified `rate-limit.conf` file, which contains:

- **Persistence settings** — Optionally configures Redis for progressive failure backoff shared across Enterprise Service instances.
- **Issuer2 endpoint limits** — Defines request limits and failure-backoff thresholds for the `token` and `credential` endpoints.
- **Verifier2 endpoint limits** — Defines request limits for the verifier service (see [Verifier2 Rate Limiting](https://docs.walt.id/enterprise-stack/services/verifier2-service/configurations/rate-limiting.md)).

**Note:**

The source IP is the IP address visible to the Enterprise Service runtime.

## Default Behavior

The service enforces endpoint request limits per issuer service, endpoint, and caller IP.

By default, the persistence section uses `type = "memory"`. For issuer2 rate limiting this means Redis is not configured:

- Basic request-volume limits still work.
- Progressive failure backoff is disabled.
- Failure counters are not stored in memory by issuer2.
- Ktor request counters are local to each Enterprise Service instance.
- Restarting an Enterprise Service instance clears its in-process request counters.

For production deployments with multiple Enterprise Service instances, configure Redis so repeated failures are blocked consistently across the cluster.

## Configure Endpoint Limits

Use the `issuer2_token_endpoint` and `issuer2_credential_endpoint` sections in `rate-limit.conf` to configure the `/openid4vci/token` and `/openid4vci/credential` endpoint limits.

```hocon[rate-limit.conf]
# Issuer2 OpenID4VCI rate limits
issuer2_token_endpoint {
  requestsPerMinute = 5
  failureWindowSeconds = 60
  failureThreshold = 5
  failureBlockSeconds = 300
}

issuer2_credential_endpoint {
  requestsPerMinute = 10
  failureWindowSeconds = 60
  failureThreshold = 5
  failureBlockSeconds = 300
}
```

## Fields

### `requestsPerMinute`

_Integer_ — Maximum number of requests allowed per minute for the same issuer service, endpoint, and caller IP.

- `issuer2_token_endpoint.requestsPerMinute` defaults to `5`.
- `issuer2_credential_endpoint.requestsPerMinute` defaults to `10`.

When the threshold is exceeded, issuer2 returns `429 Too Many Requests` with a `Retry-After` header.

### `failureWindowSeconds`

_Integer_ — Time window in seconds for counting failed endpoint responses.

The default is `60`. With the default settings, issuer2 counts failures during a rolling 60-second window.

### `failureThreshold`

_Integer_ — Number of failed requests in the failure window required to create a temporary block.

The default is `5`. With Redis enabled, the fifth failed request in the window creates a temporary backoff block.

### `failureBlockSeconds`

_Integer_ — Duration in seconds for the temporary block after the failure threshold is reached.

The default is `300`. Blocked requests return `429 Too Many Requests` with a `Retry-After` header.

## Configure Redis Backoff

Use the `persistence` section in `rate-limit.conf` to enable Redis-backed progressive failure backoff. This configuration is shared between issuer2 and verifier2 services.

```hocon[rate-limit.conf]
persistence {
  type = "redis"
  nodes = [
    { host = "redis", port = 6379 }
  ]

  # Optional Redis authentication:
  # user = "default"
  # password = "change-me"
}
```

Redis cluster deployments can use `type = "redis-cluster"`:

```hocon[rate-limit.conf]
persistence {
  type = "redis-cluster"
  nodes = [
    { host = "redis-node-1", port = 6379 },
    { host = "redis-node-2", port = 6379 },
    { host = "redis-node-3", port = 6379 }
  ]
}
```

When Redis is configured, progressive failure backoff is shared across Enterprise Service instances using the same Redis deployment.

## Monitoring

Issuer2 exposes Prometheus counters for request outcomes and failure backoff. Use these metrics to alert on automated attacks or abnormal client behavior:

| Metric | Description |
|---|---|
| `issuer2_openid4vci_requests_total` | Token and credential endpoint responses labeled by endpoint and result. |
| `issuer2_token_failures_total` | Token endpoint OAuth failures labeled by bounded OAuth error code. |
| `issuer2_token_backoff_blocks_total` | Token endpoint backoff blocks created. |
| `issuer2_token_backoff_rejections_total` | Token endpoint requests rejected by failure backoff. |
| `issuer2_credential_failures_total` | Credential endpoint failures labeled by bounded error code. |
| `issuer2_credential_backoff_blocks_total` | Credential endpoint backoff blocks created. |
| `issuer2_credential_backoff_rejections_total` | Credential endpoint requests rejected by failure backoff. |
