Open-Source Wikis

/

Vault

/

Systems

/

Quotas

hashicorp/vault

Quotas

Vault supports two kinds of quotas: rate limits (requests per unit time) and lease counts (maximum outstanding leases). Both are configured per (namespace, mount, role) tuple. Source: vault/quotas/ (7 files).

Purpose

  • Protect storage and downstream systems from runaway clients.
  • Bound how many secrets a single tenant can hold open at once.
  • Provide a uniform CLI/API surface for both quota kinds.

Directory layout

vault/quotas/
├── quotas.go                       # Quota types, manager, persistence
├── quotas_rate_limit.go            # rate-limit implementation
├── quotas_rate_limit_oss.go        # CE stub
├── quotas_util.go
└── leaseaction_enumer.go           # generated

Key abstractions

Symbol File Description
Manager vault/quotas/quotas.go Owns all quotas; receives every request for evaluation.
Quota vault/quotas/quotas.go Interface implemented by every quota type.
RateLimitQuota vault/quotas/quotas_rate_limit.go Token-bucket per (namespace, mount, role, optional source-IP).
LeaseCountQuota vault/quotas/quotas.go Maximum outstanding leases for a scope.

Configuration

vault write sys/quotas/config rate_limit_exempt_paths='sys/health'

vault write sys/quotas/rate-limit/global \
    name=global \
    rate=2000 \
    interval=1s \
    block_interval=10s

vault write sys/quotas/lease-count/db-prod \
    name=db-prod \
    path=database/ \
    max_leases=5000

The sys/quotas/... paths are surfaced in vault/logical_system_quotas.go (22k lines).

How rate limits work

sequenceDiagram
    participant H as http/handler.go
    participant Q as Manager
    participant Bucket as Token bucket
    H->>Q: evaluate(req)
    Q->>Bucket: take(1)
    alt token available
        Bucket-->>Q: allowed
        Q-->>H: ok
    else exceeded
        Bucket-->>Q: denied (block_interval starts)
        Q-->>H: 429 with Retry-After
    end

The token bucket is in-memory only; it's not replicated to other nodes. When block_interval is set, exceeding the bucket starts a hard block instead of allowing immediate retries.

How lease-count quotas work

The expiration manager calls Manager.QuotasMatched(...) whenever a new lease is registered. If the matched lease-count quota is at its limit, the request fails with ErrLeaseCountQuotaExceeded. Lease counts include leases held by the issuer's children (since revoking a parent revokes children).

Lease counts are tracked in shared state across HA nodes — the active node owns the counter and forwarded writes fail-fast against it.

Exemptions

sys/quotas/config accepts rate_limit_exempt_paths and enable_rate_limit_audit_logging/enable_rate_limit_response_headers. The rate-limit subsystem optionally tags responses with quota usage headers so clients can pace themselves without trial-and-error.

Integration points

  • Core.HandleRequest calls Manager.ApplyQuotaCheck before routing.
  • ExpirationManager.Register calls Manager.LeaseCountIncrement when minting a lease.
  • Audit captures when a request is denied for quota reasons.
  • The CLI surface (vault read|write|list sys/quotas/...) is in command/operator_*.go indirectly (through vault read|write).

Entry points for modification

  • Add a new quota type: implement Quota in vault/quotas/, register CRUD paths in vault/logical_system_quotas.go.
  • Tune rate-limit defaults: vault/quotas/quotas_rate_limit.go.
  • Surface a new metric: Manager exposes hooks for prometheus metrics already.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Quotas – Vault wiki | Factory