# Key and Credential Rotation All rotations are staged in the test environment first. Never print raw keys, DSNs, STS tokens, Presigned URLs, or Secret file contents. Every cutover needs a rollback copy outside Git and a post-change readback. ## Dify Bearer key Dify rotation uses two SHA-256 hash slots so old and new callers can overlap briefly. 1. Generate the new raw key in an approved secret manager. 2. Calculate its SHA-256 digest without placing the raw key in shell history. 3. Set the digest as `DIFY_KEY_HASH_NEXT`; leave `DIFY_KEY_HASH_CURRENT` unchanged. 4. Recreate only the Adapter and verify both old and new keys. 5. Update Dify to the new raw key and verify real test retrieval. 6. Set the new digest as `DIFY_KEY_HASH_CURRENT` and clear `DIFY_KEY_HASH_NEXT`. 7. Recreate and verify that the new key works and old key fails. 8. Revoke/delete the old raw key from its secret store. Rollback before step 6: restore the previous env file. Rollback after step 6: temporarily restore old current plus new next, recreate, and investigate. Raw keys never enter Compose environment; only `DIFY_KEY_HASH_CURRENT` and `DIFY_KEY_HASH_NEXT` do. ## WeKnora API Key 1. Create a new restricted WeKnora API Key without revoking the old key. 2. Write it to a sibling untracked Secret file using an approved secret manager/editor. 3. Set owner `10001:10001`, mode `0400`, and verify non-empty without printing. 4. Atomically replace `/opt/knowledge-adapter/secrets/weknora_api_key` on the same filesystem. 5. Recreate only the Adapter and run allowlisted retrieval. 6. Confirm request IDs reach WeKnora and logs contain no key. 7. Revoke the old WeKnora API Key. Rollback: restore the previous Secret file atomically and recreate only the Adapter before revoking the old key. ## Adapter DB credential The Adapter DB account may read/write only Adapter-owned mapping objects. 1. Create a new dedicated login/password and grant the same narrow privileges. 2. Test the new DSN from an isolated test client without displaying it. 3. Atomically replace `asset_database_url` with owner `10001:10001`, mode `0400`. 4. Recreate only the Adapter. 5. Verify mapping lookup, conflict-safe insert, and stable UUID redirect. 6. Disable the old login, observe, then remove it after the rollback window. Rollback: re-enable the old login if needed, restore the previous Secret file, and recreate only the Adapter. Do not alter `asset_mapping` rows. ## WeKnora read-only DB credential The WeKnora read-only DB account is separate from the Adapter DB account. 1. Create a new `NOINHERIT` login with no unrelated memberships. 2. Apply/review `deploy/sql/weknora_readonly_grants.sql` for the new role. 3. Prove permitted field-level SELECT succeeds and unrelated table/column/write access fails. 4. Atomically replace `weknora_readonly_database_url` with mode `0400`. 5. Recreate only the Adapter and verify first-time resource resolution. 6. disable the old login, observe, then remove it. Rollback: restore the old role and Secret file; no WeKnora schema or data changes are part of rotation. ## OSS static AK The Adapter reads the OSS AccessKey pair from two mode-`0400` Secret files. Test and production use different RAM users, keys, buckets, and Secret directories. 1. Create a second AccessKey for the same dedicated RAM user, or create a replacement dedicated RAM user with the same reviewed `oss:GetObject` policy. 2. Write the candidate ID and secret to sibling untracked files without printing either value. 3. Set owner `10001:10001`, mode `0400`, then atomically replace both active files within one maintenance window. 4. Recreate only the Adapter and verify 302 generation, object retrieval, anonymous direct denial, and absence of List/Put/Delete. 5. Keep the old pair available only for the bounded rollback window, then revoke it in RAM and securely remove the old files. Rollback: atomically restore both previous Secret files and recreate only the Adapter. Never put either AccessKey value in Compose environment variables. ## TLS certificate Renew the certificate/key outside Git, validate the full Nginx configuration, reload Nginx, and verify certificate chain/hostname/expiry. Rollback by restoring the previous certificate pair and reloading. Adapter containers do not receive TLS private keys. ## Rotation evidence For every credential class, record only: - change ticket/time; - credential identity or role name, never value; - old/new activation state; - exact candidate image/config revision; - sanitized health and E2E result; - rollback result or rollback-window expiry.