> ## Documentation Index
> Fetch the complete documentation index at: https://developers.jobhandy.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Rotate API keys

> Replace a JobHandy API key without downtime and retire the old credential after verification.

Use this runbook for planned rotation or replacement of a credential that might be exposed.

## Preparation

* Identify every runtime, worker, scheduled task, and secret reference using the old key.
* Record the old key's name and scope without copying the secret value.
* Confirm who has the required IT, HR, or Company-Admin portal permission.
* Choose a maintenance window if the client cannot reload secrets dynamically.
* Prepare a rollback path that re-enables the old key only when it is still trusted.

## Rotation flow

```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}}
sequenceDiagram
    participant Admin as Administrator
    participant Portal as JobHandy administration
    participant Secrets as Secret manager
    participant Runtime as Integration runtime
    participant API as JobHandy API
    participant Monitor as Monitoring

    Admin->>Portal: Create replacement key with required scope
    Portal-->>Admin: Display key once
    Admin->>Secrets: Store replacement version
    Secrets-->>Runtime: Deploy replacement
    Runtime->>API: Protected health/read check with new key
    API-->>Runtime: Success + X-Request-ID
    Runtime->>Monitor: Confirm all instances use new secret
    Admin->>Portal: Deactivate old key
    Monitor->>Monitor: Observe authentication failures
    alt Rollout healthy
        Admin->>Portal: Delete old key after agreed verification period
    else Rollout failure and old key still trusted
        Admin->>Portal: Reactivate old key
        Runtime->>Secrets: Roll back secret version
    end
```

## Verification requests

Use a protected read that is valid for the key scope. `GET /health` is insufficient because it does not authenticate.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl --request GET \
  --url 'https://api.jobhandy.io/v1/employees?page=1&pageSize=1' \
  --header 'X-API-Key: REPLACEMENT_API_KEY' \
  --header 'X-Request-ID: {{requestId}}'
```

## Emergency replacement

If a key may be compromised:

1. Deactivate it immediately.
2. Stop affected integration instances if necessary.
3. Review request IDs, times, tenants, and operations in available logs.
4. Create a replacement with the minimum required scope.
5. Deploy and verify the replacement.
6. Delete the old key when the investigation and rollback decision permit.

## Completion checklist

* [ ] Every runtime uses the replacement secret version
* [ ] A protected request succeeded for every required tenant context
* [ ] No new `INVALID_API_KEY` failures are caused by stale instances
* [ ] The old key is inactive
* [ ] The old key is deleted when rollback is no longer required
* [ ] Rotation date, operator, scope, and verification request IDs are recorded
