# API security operations

SSRF controls, secrets handling, transport headers, security logging and security tests, summarised in SKILL.md.

## Contents

- SSRF controls
- Secrets and keys
- Transport and headers
- Logging and detection
- Testing security controls

## Secrets and keys

- Load secrets from the platform secret store (AWS Secrets Manager, GCP Secret
  Manager, Vault, Kubernetes secrets with encryption at rest), never from the
  repository. Scan commits with a secret scanner in CI.
- Separate keys per environment and per service; rotate on a schedule and on
  every staff departure that had access.
- Hash API keys at rest (store a SHA-256 of a high-entropy key, show a prefix
  for identification), and let customers create, scope and revoke their own.
- Never log tokens, keys, passwords or full card numbers; redact at the logger.

## Transport and headers

- TLS 1.2 minimum, 1.3 preferred; redirect or refuse plain HTTP.
- `Strict-Transport-Security: max-age=31536000; includeSubDomains`.
- `Cache-Control: no-store` on responses that carry personal data or tokens.
- `X-Content-Type-Options: nosniff`; for APIs, a restrictive
  `Content-Security-Policy: default-src 'none'` costs nothing.

## Logging and detection

Log security-relevant events as structured records with a request id: sign-in
success and failure, token refresh, permission denials, rate limit hits,
password and email changes, admin actions. Alert on bursts of 401/403/404 from
one identity (enumeration), unusual geographies, and spikes on sensitive flows.
Keep logs free of secrets and minimise personal data in them.

## Testing security controls

Security checks are code and belong in the test suite:

```ts
test("a user cannot read another account's order", async () => {
  const alice = await login("alice");
  const bobsOrder = await createOrderAs("bob");
  const res = await api.get(`/orders/${bobsOrder.id}`, { token: alice });
  assert.equal(res.status, 404);
});
```

- One BOLA test per resource type, one function-level test per privileged route.
- A test that unknown or privileged fields in a write are ignored or rejected.
- A test that oversized bodies and pages are refused.
- Dependency audit (`npm audit`, `pip-audit`, OSV scanner) and a DAST pass
  (OWASP ZAP baseline) in CI for public surfaces.

## SSRF controls

*Does any endpoint fetch a URL the caller supplied?*

Webhook targets, image imports, link previews. Allowlist schemes and hosts,
resolve DNS and reject private, loopback and link-local ranges (including cloud
metadata at `169.254.169.254`), disable redirects or re-check each hop, and run
fetchers in an egress-restricted network.
