# Security Model

`@tidbcloud/auth-js` enforces a TiDB-native Supabase-like application boundary. The SDK is designed for published Data APIs and Auth-aware application requests, not database administration or PostgreSQL compatibility.

Security is part of the public contract. A release is not production-ready if runtime boundaries, redaction, forbidden capabilities, fixture contracts, or package contents cannot be verified.

## Trust Boundaries

| Boundary | Allowed | Forbidden |
| --- | --- | --- |
| Browser application | public client key, user JWT, published Data API requests | service keys, admin helpers, raw SQL, DDL, DCL, RPC, server-only imports |
| Server application | public client key, optional user JWT, controlled server-side integration | Service Keys on public Data/Schema routes, policy bypass, raw SQL through public SDK |
| Edge application | explicit fetch/storage, public client key, user JWT | Node-only assumptions, implicit persistent process storage, bundled service secrets |
| Type generation | published metadata such as `/schema` or `/doc` | direct TiDB introspection from application SDK code |

## Credential Classes

### Public Client Key

The public client key identifies the application/project context for published Data API requests.

Rules:

- may be used in browser applications
- must be sent as `apikey`
- must not be treated as a user identity token
- should be rotated if leaked outside expected public distribution

### User JWT

The user JWT identifies the authenticated user/session.

Rules:

- sent as `Authorization: Bearer <user-jwt>`
- must be paired with `apikey` for authenticated Data API calls
- must not be used as a replacement for the client key
- must be redacted from logs, errors, hooks, telemetry, and snapshots

### Service Key

Service Keys may exist for separate internal or operations APIs, but they are not Public Data/Schema credentials.

Rules:

- no public runtime entry accepts or exports Service Key client helpers
- the SDK must never generate `X-Service-Key` for `/doc`, `/schema`, or `/table` requests
- a non-empty `X-Service-Key` is rejected by the service with `401 service_key_not_allowed`
- caller-provided Service Key headers must be removed before public requests
- service keys must not be persisted in generated types, browser bundles, source maps, logs, docs examples, or package fixtures

## Required Headers

Anonymous or public client-key request:

```http
apikey: <client-key>
```

Authenticated request:

```http
apikey: <client-key>
Authorization: Bearer <user-jwt>
```

There is no Service Key header form for Public Data or Schema requests. Server applications use the same Client Key header and may add a user JWT when authenticated policy context is required.

## Forbidden Capability Boundary

The SDK must not expose or generate requests for:

- raw SQL
- arbitrary query execution
- DDL
- DCL
- grant or revoke
- schema mutation through public Data API
- SQL console
- RPC, procedures, routines, or database functions
- admin routes
- system routes
- MCP routes
- UI/dashboard routes
- transaction scripting through headers
- PostgreSQL `RETURNING`
- PostgREST embedded relationship or aggregate grammar
- direct database introspection

Stable unsupported errors are preferred over partial, surprising, or unsafe compatibility behavior.

## Runtime Entry Policy

### Browser

Browser entry points must:

- accept public client keys only
- request user tokens through Auth/session APIs or caller-provided callbacks
- reject or omit service-key APIs
- keep redaction active for diagnostics
- pass bundle scans that prove service-key paths are absent

### Server

Server entry points must:

- separate server-only exports from browser exports
- reject or omit Service Key Public Data/Schema helpers
- preserve audit metadata such as request ids
- strip caller-provided Service Key headers before public requests
- prevent policy bypass assumptions

### Edge

Edge entry points must:

- avoid Node-only APIs unless explicitly guarded
- avoid implicit process-global persistent session storage
- support caller-provided fetch/storage patterns
- maintain the same forbidden capability boundary as browser/server

## Redaction Requirements

The following values must be redacted from errors, logs, hooks, telemetry, snapshots, source maps, dry-pack output, and release artifacts:

- `apikey`
- `Authorization`
- `X-Service-Key`
- user JWTs
- refresh tokens
- cookies
- passwords
- DSNs
- database URLs
- bearer tokens
- service-key-like strings
- full SQL strings
- secret-bearing request bodies
- secret-bearing response bodies

Redaction must handle:

- headers
- URLs and query strings
- nested JSON objects
- thrown errors
- normalized SDK error JSON
- logger and hook payloads

## Request Pipeline Security

The request pipeline must:

- generate or propagate request ids
- add SDK client info
- normalize service error envelopes
- avoid retrying unsafe mutations by default
- redact diagnostics before logger or hook invocation
- return stable error envelopes for unsupported operations

### Database replacement session boundary

The exact terminal error `session_database_changed` means the saved access and
refresh tokens belong to the project's previous database. The shared client
clears only the matching saved session, stops its automatic refresh, and emits
`SIGNED_OUT` to local listeners and other tabs. It does not place a DSN, binding
ID, target fingerprint, runtime revision, or database selector in browser
storage or request headers. Network failures, `5xx` responses, and ordinary
authorization or policy errors must leave the current session untouched.
- preserve enough status and request-id context for support without leaking secrets

## Fixture-Based Security Contract

Release candidates must stay aligned with service fixtures:

- positive fixtures cover allowed published Data API requests
- negative fixtures cover forbidden capabilities
- compatibility fixtures cover stable auth and route errors
- security mode fixtures keep service-key mode server-side only

The SDK must fail tests if it generates forbidden routes or forbidden headers.

## Package And Bundle Security

Before release:

- browser bundle scans must prove service-key helpers and server-only paths are absent
- `npm pack --dry-run` output must match the release allowlist
- source maps and declaration files must not contain secrets
- generated fixtures must not contain live credentials
- docs examples must use placeholders only
- dependency audit policy must be reviewed

## Incident Response Expectations

If a secret leak or forbidden capability exposure is discovered:

- stop publication or unpublish the release candidate if possible
- rotate affected keys
- identify the runtime entry and package artifact that leaked the capability
- add a regression test under security, export, bundle, or contract tests
- update this document if the boundary was ambiguous
- publish a changelog entry describing the fix and user action required
