Implement OAuth flows and manage credentials for external services (Google, Slack, Salesforce, etc.) through Interactor. Use when connecting users to third-party services, handling OAuth authorization, retrieving access tokens, or monitoring credential status.
Securely store and manage OAuth tokens and API keys for external services through the Interactor platform.
interactor-auth skill)Interactor handles credential complexity for both OAuth tokens and API keys:
| Feature | Description |
|---|---|
| Token Storage | Encrypted storage of access tokens, refresh tokens, and API keys |
| Automatic Refresh | OAuth tokens are refreshed before expiry |
| Multi-tenant Isolation | Namespaces separate different users' credentials |
| Revocation Handling | Detects when users revoke OAuth access |
| Unified Interface | Same API for OAuth and API key credentials |
Critical: All Interactor API calls must be made from your backend server.
Interactor does not authenticate your end users directly. Your application:
Never expose to client-side code:
cred_abc)┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Browser/App │ │ Your Backend │ │ Interactor │
│ (Frontend) │ │ (Server) │ │ API │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
│ User action │ │
│──────────────────────>│ │
│ │ │
│ │ API call with JWT │
│ │──────────────────────>│
│ │ │
│ │ Credential/token │
│ │<──────────────────────│
│ │ │
│ Response (no tokens) │ │
│<──────────────────────│ │
Namespaces provide multi-tenant isolation for credentials. Interactor supports several strategies:
| Pattern | Namespace Value | Use Case |
|---|---|---|
| Per-user | user_123 | Each user has their own credentials |
| Per-organization | org_456 | Shared credentials within an organization |
| Shared/Global | shared or default | Company-wide credentials (e.g., shared Slack bot) |
| Account-level | (omit parameter) | Credentials accessible to all API calls |
Namespace behavior:
// Per-user credential (isolated)
{ namespace: "user_123", service_id: "google_calendar" }
// Shared credential (accessible by multiple users)
{ namespace: "shared", service_id: "slack" }
// Account-level credential (omit namespace)
{ service_id: "salesforce" } // Accessible to all API calls
Important: If namespace is omitted, credentials are created at the account level and are accessible to all API calls using that account's authentication.
Hybrid patterns:
prod_user_123, staging_user_123)Note: Fine-grained access control (role-based permissions, credential-to-workflow binding) is managed at the account level through Interactor's admin interface. The API does not currently expose permission management endpoints.
Credentials within a namespace are accessible to any authenticated request that includes that namespace. For granular control:
Get all credentials in your account:
curl https://core.interactor.com/api/v1/credentials \
-H "Authorization: Bearer <token>"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
namespace | string | Filter by namespace (e.g., user_123) |
service_id | string | Filter by service (e.g., google_calendar) |
status | string | Filter by status: active, expired, revoked |
Example - List credentials for a specific user:
curl "https://core.interactor.com/api/v1/credentials?namespace=user_123" \
-H "Authorization: Bearer <token>"
Response (structure inferred from credential object pattern):
{
"data": {
"credentials": [
{
"id": "cred_abc",
"service_id": "google_calendar",
"service_name": "Google Calendar",
"namespace": "user_123",
"status": "active",
"scopes": ["calendar.readonly", "calendar.events"],
"created_at": "2026-01-15T10:00:00Z",
"expires_at": "2026-02-01T00:00:00Z"
}
]
}
}
Get a high-level summary grouped by namespace:
curl https://core.interactor.com/api/v1/credentials/summary \
-H "Authorization: Bearer <token>"
Response:
{
"data": {
"namespaces": {
"user_123": [
{
"id": "cred_abc",
"service_id": "google_calendar",
"service_name": "Google Calendar",
"status": "active",
"scopes": ["calendar.readonly", "calendar.events"],
"expires_at": "2026-02-01T00:00:00Z"
}
],
"user_456": [
{
"id": "cred_def",
"service_id": "slack",
"service_name": "Slack",
"status": "active",
"scopes": ["channels:read", "chat:write"]
}
]
},
"total_count": 2
}
}
curl https://core.interactor.com/api/v1/credentials/cred_abc \
-H "Authorization: Bearer <token>"
Response (structure inferred from credential object pattern):
{
"data": {
"id": "cred_abc",
"service_id": "google_calendar",
"service_name": "Google Calendar",
"namespace": "user_123",
"status": "active",
"scopes": ["calendar.readonly", "calendar.events"],
"metadata": {
"email": "[email protected]"
},
"created_at": "2026-01-15T10:00:00Z",
"last_refreshed_at": "2026-01-20T11:00:00Z",
"expires_at": "2026-02-01T00:00:00Z"
}
}
Retrieve the current access token. Automatically refreshes if expired.
curl https://core.interactor.com/api/v1/credentials/cred_abc/token \
-H "Authorization: Bearer <token>"
Response:
{
"data": {
"access_token": "ya29.a0AfH6SM...",
"token_type": "Bearer",
"expires_in": 3600
}
}
Use this token to call the external service's API directly:
# Example: Call Google Calendar API
curl "https://www.googleapis.com/calendar/v3/calendars/primary/events" \
-H "Authorization: Bearer ya29.a0AfH6SM..."
Manually trigger a token refresh:
curl -X POST https://core.interactor.com/api/v1/credentials/cred_abc/refresh \
-H "Authorization: Bearer <token>"
Response (structure inferred):
{
"data": {
"id": "cred_abc",
"status": "active",
"last_refreshed_at": "2026-01-20T12:00:00Z"
}
}
Delete a credential (revokes OAuth tokens if applicable):
curl -X DELETE https://core.interactor.com/api/v1/credentials/cred_abc \
-H "Authorization: Bearer <token>"
Response: 204 No Content on success.
Start an OAuth flow to connect an external service:
curl -X POST https://core.interactor.com/api/v1/oauth/initiate \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"service_id": "google_calendar",
"namespace": "user_123",
"scopes": ["calendar.readonly", "calendar.events"],
"redirect_uri": "https://yourapp.com/oauth/callback"
}'
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
service_id | string | Yes | Service identifier (e.g., google_calendar, slack) |
namespace | string | Yes | User namespace for data isolation (or omit for account-level) |
scopes | array | No | OAuth scopes to request (defaults to service's default scopes) |
redirect_uri | string | Yes | Where to redirect after authorization |
Scope Validation & Mapping:
Interactor validates and maps scopes at different stages:
| Stage | Validation |
|---|---|
/oauth/initiate | Basic validation against service's known scopes |
| Authorization | Provider validates scopes; user may grant subset |
| Token exchange | Final granted scopes stored with credential |
Interactor uses simplified scope identifiers that map to provider-specific OAuth URLs:
calendar.readonly → https://www.googleapis.com/auth/calendar.readonly