Skip to main content

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

text
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

StatusDescription
activeToken is valid. Refresh will be attempted before expiry.
failedThree consecutive refresh attempts failed. User must re-authorize.
revokedManually revoked via the dashboard API.

List Connections

Retrieve all OAuth connections for an application, paginated:

bash
curl "https://api.yorauth.com/api/dashboard/applications/{applicationId}/connections" \
  -H "Authorization: Bearer your-api-key"

Filter by status:

bash
curl "https://api.yorauth.com/api/dashboard/applications/{applicationId}/connections?status=active&per_page=25" \
  -H "Authorization: Bearer your-api-key"

Query Parameters:

ParameterTypeDescription
statusstringFilter by active, failed, or revoked
per_pageintegerResults per page, maximum 100 (default: 15)

Response:

json
{
  "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

FieldDescription
idUUID of the connection record
user_idThe external user identifier passed when initiating the OAuth flow
external_user_idCanonical external user reference (same as user_id)
app_user_idUUID of the managed app user, if the flow was initiated in managed mode
providerProvider name, identifier, and logo from the marketplace
provider_user_idThe user's ID as returned by the provider (e.g. Google's numeric user ID)
provider_user_infoProfile data returned by the provider: email, name, avatar
statusactive, failed, or revoked
token_typeAlways Bearer
scopesScopes granted by the user
expires_atWhen the current access token expires (null if provider does not expire tokens)
last_refreshed_atWhen the token was last successfully refreshed
revoked_atWhen 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.

bash
curl -X POST "https://api.yorauth.com/api/dashboard/applications/{applicationId}/connections/{connectionId}/revoke" \
  -H "Authorization: Bearer your-api-key"

Response (200):

json
{
  "data": {
    "id": "conn-uuid-...",
    "status": "revoked",
    "revoked_at": "2026-02-25T12:30:00+00:00"
  }
}

Error — already revoked (409):

json
{
  "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 with Crypt::encryptString() (AES-256-CBC)
  • refresh_token_encrypted — The refresh token, encrypted with Crypt::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_encrypted is updated, expires_at is recalculated, last_refreshed_at is set to now, failed_refresh_count is reset to 0
  • On failure: failed_refresh_count is incremented and last_error is recorded
  • After 3 consecutive failures: the connection status is set to failed and the connection.failed webhook 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.

EventWhen
connection.createdA new connection is created (first-time authorization)
connection.refreshedA token refresh succeeds
connection.failedThree refresh attempts fail consecutively
connection.revokedA 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_id
  • provider
  • provider_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.