Credential Rotation Guide
This guide documents how to rotate API keys and credentials used by DocuElevate, along with onboarding and offboarding procedures for team members and service accounts.
Overview
DocuElevate integrates with several external services that require API keys, tokens, or passwords. Regularly rotating these credentials limits the blast radius of a potential leak and is a security best practice.
Credentials fall into two categories:
| Category | Examples |
|---|---|
| API keys | OpenAI API key, Azure AI key, Paperless-ngx API token, AWS access keys |
| OAuth tokens / secrets | Dropbox, Google Drive, OneDrive, SharePoint, Authentik client secrets and refresh tokens |
| Passwords | Admin password, Nextcloud, Email (SMTP), IMAP, FTP, SFTP, WebDAV |
| Private keys | SFTP private key and passphrase |
All credentials are stored either in environment variables or, when set via the Settings UI, encrypted in the database using Fernet symmetric encryption (keyed from SESSION_SECRET).
Recommended Rotation Schedule
| Credential Type | Recommended Rotation Interval |
|---|---|
| API keys (OpenAI, Azure, AWS, Paperless) | Every 90 days |
| OAuth client secrets | Every 180 days |
| OAuth refresh tokens | Rotate on revocation / after each re-authorization |
| Passwords (SMTP, IMAP, FTP, SFTP, Nextcloud, WebDAV) | Every 90 days or on personnel change |
| Admin password | Every 90 days or on personnel change |
SESSION_SECRET |
On suspected compromise; note all active sessions will be invalidated |
How to Rotate a Credential
DocuElevate supports two rotation methods:
Method 1 — Settings API (recommended, zero-downtime)
Use the Settings REST API to update individual credentials while the application is running. No restart is needed for most credentials (check restart_required in the response).
# Rotate the OpenAI API key
curl -X POST https://<your-host>/api/settings/openai_api_key \
-H "Content-Type: application/json" \
-b "session=<admin-session-cookie>" \
-d '{"key": "openai_api_key", "value": "sk-new-key-here"}'
The endpoint returns "restart_required": true for settings that require an application restart to take effect (e.g., database URL, session secret). All AI-service and storage-provider credentials take effect immediately without a restart.
Method 2 — Environment variable / .env file
- Update the relevant variable in your
.envfile (or your container/Kubernetes secret). - Restart the application so the new value is loaded:
docker compose restart api worker
Note: Settings stored in the database take precedence over environment variables. If you previously set a credential via the Settings UI, you must also update or delete it from the database (via the Settings API) to have the environment variable take effect.
Per-Credential Rotation Procedures
OpenAI API Key
- Log in to platform.openai.com → API keys.
- Create a new secret key and copy it.
- Update in DocuElevate:
POST /api/settings/openai_api_key {"key": "openai_api_key", "value": "<new-key>"} - Verify document processing still works (upload a test file).
- Delete the old key in the OpenAI dashboard.
Azure Document Intelligence Key
- Open portal.azure.com → your Document Intelligence resource → Keys and Endpoint.
- Regenerate Key 2 while Key 1 is still live (avoids downtime).
- Update
azure_ai_keyin DocuElevate with the new key. - Verify connectivity, then regenerate Key 1 and optionally update again.
AWS S3 Access Keys
- In the IAM Console, create a new access key for the service user.
- Update both
aws_access_key_idandaws_secret_access_keyin DocuElevate together (use the bulk-update endpoint or update both settings in sequence before verifying). - Test an S3 upload from DocuElevate.
- Deactivate the old IAM access key, then delete it after 24 hours.
Dropbox App Credentials & Refresh Token
Dropbox refresh tokens are long-lived; rotate them by re-authorizing the application:
- In dropbox.com/developers, revoke the existing token.
- Follow the Dropbox OAuth flow documented in
docs/DropboxSetup.mdto obtain a new refresh token. - Update
dropbox_refresh_token(anddropbox_app_key/dropbox_app_secretif also rotating those).
Google Drive OAuth Credentials
- In the Google Cloud Console, navigate to APIs & Services → Credentials.
- Rotate the OAuth client secret: delete the old secret and create a new one.
- Update
google_drive_client_secretin DocuElevate. - Re-authorize to obtain a fresh refresh token and update
google_drive_refresh_token.
For service-account credentials (google_drive_credentials_json):
- Create a new service-account key in the Google Cloud Console.
- Update
google_drive_credentials_jsonwith the new JSON. - Verify access, then delete the old key.
OneDrive (Microsoft OAuth)
- In Azure App Registrations, navigate to Certificates & secrets for your app.
- Add a new client secret.
- Update
onedrive_client_secretin DocuElevate. - Re-authorize via the OAuth flow to get a fresh
onedrive_refresh_token. - Delete the old client secret in Azure.
SharePoint (Microsoft OAuth)
- SharePoint uses the same Azure AD app registration as OneDrive.
- In Azure App Registrations, navigate to Certificates & secrets for your app.
- Add a new client secret.
- Update
sharepoint_client_secretin DocuElevate. - Re-authorize via the OAuth flow to get a fresh
sharepoint_refresh_token. - Delete the old client secret in Azure.
Authentik (OIDC)
- In your Authentik admin panel, navigate to the DocuElevate application and regenerate the client secret.
- Update
authentik_client_secretin DocuElevate. - Restart the application (this setting requires a restart:
restart_required: true).
Paperless-ngx API Token
- Log in to your Paperless-ngx instance → Settings → API Tokens.
- Create a new token.
- Update
paperless_ngx_api_tokenin DocuElevate. - Verify document routing works, then revoke the old token.
SMTP / Email Password
- Rotate the password in your mail server or email provider.
- Update
email_passwordin DocuElevate.
IMAP Passwords
Update imap1_password and/or imap2_password after rotating the credentials with your email provider.
Nextcloud Password / App Password
- In Nextcloud → Settings → Security, revoke the existing app password and create a new one.
- Update
nextcloud_passwordin DocuElevate.
FTP / SFTP / WebDAV Passwords
- Rotate the credential on the respective server.
- Update
ftp_password,sftp_password, orwebdav_passwordin DocuElevate.
SFTP Private Key
- Generate a new key pair:
bash ssh-keygen -t ed25519 -f ~/.ssh/docuelevate_sftp -C "docuelevate-sftp" - Install the new public key on the SFTP server.
- Update
sftp_private_key(andsftp_private_key_passphraseif encrypted) in DocuElevate. - Verify connectivity, then remove the old public key from the SFTP server.
Admin Password
- Update
admin_passwordin DocuElevate (via the Settings UI or API). - Communicate the new password to any users who share it (discouraged; prefer individual accounts via OAuth).
- Requires application restart.
SESSION_SECRET
Warning: Rotating
SESSION_SECRETinvalidates all active user sessions. All logged-in users will be signed out immediately.
- Generate a new secret (minimum 32 characters):
bash python -c "import secrets; print(secrets.token_hex(32))" - Update the environment variable or
.envfile. - Restart the application.
- Existing encrypted settings stored in the database will no longer be readable because the encryption key is derived from
SESSION_SECRET. You must re-enter all sensitive settings that were stored via the UI after rotating this value.
Bulk Credential Audit
Use the dedicated endpoint to list all credential settings and their configured/unconfigured status:
GET /api/settings/credentials
Example response:
{
"credentials": [
{
"key": "openai_api_key",
"category": "AI Services",
"description": "OpenAI API key for metadata extraction",
"configured": true,
"source": "env"
},
{
"key": "azure_ai_key",
"category": "AI Services",
"description": "Azure AI key for document intelligence",
"configured": true,
"source": "db"
},
...
],
"total": 24,
"configured_count": 8,
"unconfigured_count": 16
}
The source field indicates whether the value comes from the database (db) or an environment variable (env).
Onboarding a New Team Member or Service Account
- Identify required credentials – Use
GET /api/settings/credentialsto see which credentials are active in the deployment. - Create service-specific credentials – For each external service (OpenAI, AWS, etc.) create a new API key or sub-account rather than sharing the existing one. This enables individual revocation without disrupting others.
- Set credentials via the Settings API – Provide the new credential via
POST /api/settings/{key}. The value is encrypted at rest. - Restrict access – Ensure the new service account has only the minimum permissions needed (e.g., an S3 IAM user with write access to the specific bucket only).
- Document the credential – Record which system generated the credential and when it was created, so it can be identified during offboarding.
Offboarding a Team Member or Decommissioning a Service Account
- Identify credentials tied to the departing user – Review all third-party services for keys or OAuth authorizations issued under their account.
- Revoke credentials – Delete or disable the API key/token in each third-party service immediately.
- Rotate shared credentials – If any credential was shared (e.g., a team-wide admin password), rotate it now using the procedures above.
- Update DocuElevate – Set the new credential via
POST /api/settings/{key}or delete the old entry viaDELETE /api/settings/{key}if the service is no longer used. - Verify operations – Trigger a test document processing run to confirm all integrations still work.
- Audit logs – Review audit logs for any anomalous activity by the departing user before revoking access.
Emergency Credential Revocation
If a credential is believed to be compromised:
- Revoke immediately in the external service (do not wait to have a replacement ready).
- Review audit logs for unauthorized usage.
- Generate and deploy a replacement credential as soon as possible.
- Notify stakeholders per your incident response plan (see SECURITY.md).
Related Documentation
- Configuration Guide — Full list of environment variables
- Deployment Guide — Deployment and restart procedures
- SECURITY_AUDIT.md — Security audit findings and status
- SECURITY.md — Security contact and disclosure policy