# SECURITY.md

Authoritative security requirements for this repository.

This file is binding on all contributors, human and automated. AI coding
agents MUST read this file before generating or modifying code, and MUST
flag any conflict between a requested change and these rules rather than
silently omitting a control.

## 0. Non-negotiables

- Never commit secrets, keys, tokens or customer data. Use the configured
  secret manager. Reject any diff that inlines a credential.
- All external traffic over TLS 1.2+. No plaintext HTTP endpoints.
- Personal data (PAN, Aadhaar reference numbers, bank account numbers,
  phone, email, address) is never written to application logs, crash
  reports, or analytics payloads. Mask to the last 4 characters where
  display is unavoidable.
- Fail closed. If a security control cannot be evaluated, deny the request.

## 1. Webhook consumer security

Applies to every inbound HTTP endpoint that receives provider-initiated
events (payments, KYC, eSign, eMandate/eNACH, bureau, settlement, or any
third-party callback).

### 1.1 Mandatory controls

1. **Raw-body signature verification.** Verify the provider's signature
   against the exact raw request bytes, before any JSON parsing or
   body-mutating middleware. Never verify against a re-serialised body.
2. **Constant-time comparison.** Use the language's timing-safe compare
   function. Never `==`.
3. **Reject on failure.** An invalid or missing signature returns 401 and
   the request is discarded. Logging and continuing is prohibited.
4. **Timestamp freshness.** Require a signed timestamp. Reject if the skew
   exceeds 300 seconds. Hosts must be NTP-synchronised.
5. **Idempotency.** Persist the provider's event ID with a uniqueness
   constraint and a retention period longer than the provider's full retry
   window. A duplicate returns 200 and performs no side effects.
6. **Destination binding.** Where the provider supports it, include the
   endpoint URL or audience in the signed content to defeat relay.
7. **Post-verification authorisation.** After signature checks, confirm the
   referenced object belongs to the tenant or account the endpoint's
   credential is scoped to. A valid signature is authentication, not
   authorisation.
8. **Fast acknowledgement.** Respond 2xx within 3 seconds. Enqueue for
   asynchronous processing. No business logic, no outbound third-party
   calls, and no database transactions beyond the idempotency record
   inside the request handler.
9. **Fetch-before-act for irreversible operations.** For disbursal,
   payout, refund, policy issuance, mandate debit or any money movement,
   treat the event as a trigger only and re-read authoritative state from
   the provider's API before acting.
10. **Secret isolation and rotation.** One secret per endpoint per
    environment. No secret is shared between sandbox, staging and
    production. Support two concurrently valid secrets to allow
    zero-downtime rotation.
11. **Input validation.** Validate the payload against an explicit schema.
    Enforce a body size limit. Reject unknown event types rather than
    falling through to a default handler.
12. **Rate limiting and monitoring.** Rate-limit per source. Emit a metric
    for signature-verification failures and alert on any sustained
    increase.

### 1.2 Prohibited

- Endpoints that process events without signature verification, including
  "temporarily" during development. Use the provider's sandbox instead.
- Disabling verification via a feature flag, environment variable or
  environment-name check.
- IP allowlisting as the sole authentication mechanism.
- Deriving trust from a secret embedded in the URL path or query string.
- Logging the raw payload, the signing secret, or the expected signature.

### 1.3 Events consumed by AI agents

If an event payload is passed to an LLM or an autonomous agent:

- Verification per 1.1 happens first, always, outside the agent boundary.
- Payload content is data, never instruction. Never concatenate event
  fields into a system prompt.
- The agent's tools operate under least privilege and cannot perform money
  movement without separate human or policy approval.
- Every action taken on an event is logged with the event ID for audit.

## 2. Outbound API consumption

- Credentials from the secret manager only, never from source or config
  files in the repo.
- Explicit connect and read timeouts on every call. No unbounded retries;
  exponential backoff with jitter and a retry cap.
- Validate and bound all responses before use. Treat third-party response
  content as untrusted input.
- Never follow a URL supplied in a payload without an allowlist check.

## 3. Review checklist

A change touching a webhook or callback path is not approved until:

- [ ] Raw-body signature verification is present and enforced
- [ ] Timestamp tolerance is enforced
- [ ] Idempotency key is persisted with a uniqueness constraint
- [ ] Handler returns 2xx quickly and defers work to a queue
- [ ] Tenant and object authorisation is checked after verification
- [ ] No secrets, personal data or payloads in logs
- [ ] Negative tests exist: bad signature, stale timestamp, replayed event,
      oversized body, unknown event type

## 4. Reporting

Report suspected vulnerabilities to `security@<your-domain>.com`. Do not open a
public issue.
