Connection Management
An OAuth connection represents a successful authorization by one of your users with a third-party provider. YorAuth stores the access token, refresh token (if issued), granted scopes, and identity information returned by the provider. Tokens are encrypted at rest and never returned in plain text through the API.
Connection Lifecycle
Flow completes
|
v
status: "active"
|
|-- token refresh succeeds ──► status: "active" (updated tokens)
|
|-- refresh fails (attempt 1 or 2) ──► failed_refresh_count incremented
|
|-- refresh fails (attempt 3) ──► status: "failed", webhook: connection.failed
|
|-- revoked via API ──► status: "revoked", revoked_at set, webhook: connection.revoked
Connection Statuses
| Status | Description |
|---|---|
active | Token is valid. Refresh will be attempted before expiry. |
failed | Three consecutive refresh attempts failed. User must re-authorize. |
revoked | Manually revoked via the dashboard API. |
List Connections
Retrieve all OAuth connections for an application, paginated:
curl "https://api.yorauth.com/api/dashboard/applications/{applicationId}/connections" \
-H "Authorization: Bearer your-api-key"
Filter by status:
curl "https://api.yorauth.com/api/dashboard/applications/{applicationId}/connections?status=active&per_page=25" \
-H "Authorization: Bearer your-api-key"
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by active, failed, or revoked |
per_page | integer | Results per page, maximum 100 (default: 15) |
Response:
{
"data": [
{
"id": "conn-uuid-...",
"user_id": "ext-user-123",
"external_user_id": "ext-user-123",
"app_user_id": null,
"provider": {
"identifier": "google",
"name": "Google",
"logo_url": "https://..."
},
"provider_user_id": "109876543210",
"provider_user_info": {
"email": "user@example.com",
"name": "Jane Smith",
"avatar": "https://lh3.googleusercontent.com/..."
},
"status": "active",
"token_type": "Bearer",
"scopes": ["openid", "email", "profile"],
"expires_at": "2026-02-25T13:00:00+00:00",
"last_refreshed_at": "2026-02-25T12:00:00+00:00",
"revoked_at": null,
"created_at": "2026-01-15T09:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"last_page": 4,
"per_page": 15,
"total": 56
}
}
Field Reference
| Field | Description |
|---|---|
id | UUID of the connection record |
user_id | The external user identifier passed when initiating the OAuth flow |
external_user_id | Canonical external user reference (same as user_id) |
app_user_id | UUID of the managed app user, if the flow was initiated in managed mode |
provider | Provider name, identifier, and logo from the marketplace |
provider_user_id | The user's ID as returned by the provider (e.g. Google's numeric user ID) |
provider_user_info | Profile data returned by the provider: email, name, avatar |
status | active, failed, or revoked |
token_type | Always Bearer |
scopes | Scopes granted by the user |
expires_at | When the current access token expires (null if provider does not expire tokens) |
last_refreshed_at | When the token was last successfully refreshed |
revoked_at | When the connection was revoked (null if not revoked) |
Revoke a Connection
Revoking a connection sets its status to revoked and records the revoked_at timestamp. The user will need to re-authorize to create a new connection.
curl -X POST "https://api.yorauth.com/api/dashboard/applications/{applicationId}/connections/{connectionId}/revoke" \
-H "Authorization: Bearer your-api-key"
Response (200):
{
"data": {
"id": "conn-uuid-...",
"status": "revoked",
"revoked_at": "2026-02-25T12:30:00+00:00"
}
}
Error — already revoked (409):
{
"error": {
"code": "CONNECTION_ALREADY_REVOKED",
"message": "This connection has already been revoked."
}
}
Revoking a connection fires the connection.revoked webhook event for your application.
Revoking in YorAuth does not call the provider's token revocation endpoint. If you need to invalidate the token at the provider level as well, you must do so separately using the provider's revocation API.
Token Storage and Encryption
Tokens are stored in the oauth_connections table in two binary columns:
access_token_encrypted— The access token, encrypted withCrypt::encryptString()(AES-256-CBC)refresh_token_encrypted— The refresh token, encrypted withCrypt::encryptString()(AES-256-CBC)
These columns are never returned by any API response. They are only accessible to internal services that decrypt them for token refresh operations.
The provider_user_info JSON column contains profile data (email, name, avatar URL) as returned by the provider at the time of the OAuth flow. This is available in API responses and webhook payloads.
Automatic Token Refresh
YorAuth automatically refreshes access tokens before they expire using the stored refresh token. The refresh is performed by a background job (RefreshOAuthTokenJob) dispatched by the scheduler.
Refresh Behavior
- A new access token is obtained by posting to the provider's token endpoint with
grant_type=refresh_token - If the provider returns a new refresh token, it replaces the stored one (some providers rotate refresh tokens)
- On success:
access_token_encryptedis updated,expires_atis recalculated,last_refreshed_atis set to now,failed_refresh_countis reset to 0 - On failure:
failed_refresh_countis incremented andlast_erroris recorded - After 3 consecutive failures: the connection status is set to
failedand theconnection.failedwebhook event is fired
Providers Without Refresh Tokens
Some providers (notably GitHub) do not issue refresh tokens for standard OAuth Apps. For these connections, refresh_token_encrypted is null and no automatic refresh occurs. The access token remains valid until the provider revokes it or the user deauthorizes the application.
Re-Authorization After Failure
When a connection enters failed status, the user must go through the OAuth flow again. A new successful flow will upsert the connection record (matching on application, provider, and provider user ID), resetting the status to active and replacing the tokens.
Webhooks
YorAuth fires webhook events on connection state changes. Configure webhooks in your application settings to receive these events.
| Event | When |
|---|---|
connection.created | A new connection is created (first-time authorization) |
connection.refreshed | A token refresh succeeds |
connection.failed | Three refresh attempts fail consecutively |
connection.revoked | A connection is revoked via the API |
See the webhook documentation for payload shapes and delivery details.
Upsert Behavior
When a user completes the OAuth flow for a provider they have previously connected, YorAuth updates the existing connection rather than creating a duplicate. The match is based on:
application_idproviderprovider_user_id(the provider's own user identifier)external_user_id/user_id(your user identifier)app_user_id(if using managed mode)
If all of these match an existing connection, that connection's tokens and status are updated. A connection.created webhook is only fired for newly created connections, not for updates.