Shared Credentials
Multiple integrations can share a single credential when they authenticate against the same provider. The primary example is Google's OAuth 2.0 — Google Drive, Gmail, and Google Calendar all use the same GOOGLE_OAUTH2 credential.
How It Works
A credential in ORQO stores fields like client_id, client_secret, access_token, and refresh_token. When multiple Apps reference the same credential_key in their manifests, they all read from and write to the same credential record.
┌──────────────┐
│ GOOGLE_OAUTH2│
│ │
│ client_id │
│ client_secret│
│ access_token │
│ refresh_token│
└──────┬───────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
Google Drive Gmail Google Calendar
(drive scope) (gmail scope) (calendar scope)
Incremental OAuth Authorization
When a user authorizes the first Google App (e.g., Drive), ORQO requests the Drive scope. When they later install Gmail, ORQO triggers a new OAuth flow requesting the Gmail scope.
Without special handling, the second authorization would replace the existing token — losing Drive access. To prevent this, all Google Apps include include_granted_scopes in their OAuth config:
{
"oauth_config": {
"authorize_url": "https://accounts.google.com/o/oauth2/auth",
"token_url": "https://oauth2.googleapis.com/token",
"scopes": ["https://www.googleapis.com/auth/gmail.modify"],
"extra_authorize_params": {
"access_type": "offline",
"prompt": "consent",
"include_granted_scopes": "true"
}
}
}
This tells Google to merge the new scope into the existing grant. The resulting token has both Drive and Gmail scopes. Each subsequent Google App adds its scope incrementally.
Token Refresh Safety
ORQO's OAuth callback handler preserves existing tokens when they're not returned in the new response. This prevents a re-authorization from accidentally clearing the refresh token if the provider omits it.
Designing for Shared Credentials
When building integrations that share a credential:
1. Use the Same credential_key
All Apps that share a credential must reference the same key in their manifest's credentials array:
// Google Drive manifest
{ "credentials": [{ "key": "GOOGLE_OAUTH2", "type": "oauth2", "label": "Google OAuth", "maps_to": "access_token" }] }
// Gmail manifest
{ "credentials": [{ "key": "GOOGLE_OAUTH2", "type": "oauth2", "label": "Google OAuth", "maps_to": "access_token" }] }
// Google Calendar manifest
{ "credentials": [{ "key": "GOOGLE_OAUTH2", "type": "oauth2", "label": "Google OAuth", "maps_to": "access_token" }] }
2. Request Only Your Scopes
Each App's oauth_config should request only the scopes it needs — incremental authorization handles the merging:
// Google Drive — only Drive scope
{ "scopes": ["https://www.googleapis.com/auth/drive"] }
// Gmail — only Gmail scope
{ "scopes": ["https://www.googleapis.com/auth/gmail.modify"] }
// Google Calendar — only Calendar scope
{ "scopes": ["https://www.googleapis.com/auth/calendar"] }
3. Enable Incremental Scopes
Add the provider's incremental authorization parameter. For Google:
{
"extra_authorize_params": {
"access_type": "offline",
"prompt": "consent",
"include_granted_scopes": "true"
}
}
4. Setup Instructions Should Reference Existing Credentials
After the first Google App is set up, subsequent Apps should tell users to reuse the credential:
{
"setup_instructions": [
"Enable the Gmail API in your Google Cloud project",
"Reuse the same OAuth 2.0 credentials you created for Google Drive",
"Link the GOOGLE_OAUTH2 credential to this app",
"Click 'Connect with OAuth' to authorize Gmail access"
]
}
When Not to Share
Don't share credentials when:
- Different providers — Slack and Google use different OAuth systems. Each gets its own credential.
- Different credential types — An OAuth2 credential and an API key credential are different even if they're for the same provider.
- Different accounts — If a user needs to connect two separate Google accounts, they need two separate credentials.
Current Shared Credential Groups
| Credential Key | Type | Shared By |
|---|---|---|
GOOGLE_OAUTH2 | oauth2 | Google Drive, Gmail, Google Calendar |
SLACK_BOT_TOKEN | api_key | Slack App, Slack Integration Skill |
GITHUB_TOKEN | api_key | GitHub App, Developer Tools Skill |