Topolo Docs Topolo Platform
Open workspace

List user OAuth providers

List external sign-in providers linked to one visible user.

Outcome

List external sign-in providers linked to one visible user.

These examples prove local handler behavior with real isolated SQL and explicitly simulated identity/permission dependencies.

Before you start

  • Verify the intended authenticated identity and the current credential-scoped action before preparing input. Self and managed-user security operations have different authority; a session id does not authorize a different user.

  • Use authorized identity and user/session discovery. Recovery security data and session/device identifiers must remain inside the caller-approved workflow.

Discover the target

topolo whoami --json
topolo apps --json
topolo actions get app_topolo_auth.user_oauth_providers.list --detail --json

Use the caller subject or a user returned by authorized users discovery. Read user_oauth_providers.list for that exact user before unlinking a returned provider name; providerUserId is an external identity. Unlock requires target-user management authority.

Input fields

FieldRequiredMeaning
userIdYesExisting Auth user id from authorized identity or user discovery. Provider links allow self or authorized managed-user access; account unlock requires target-user management authority even for a self request.

Effects

  • Reads existing external sign-in associations for self or an authorized managed user. Does not establish an alternate working sign-in method.

Interpret the response

HTTP 200 successes use raw target success/message/data/timestamp, which CLI/MCP can wrap or project. Record times are epoch seconds; the envelope timestamp is ISO text. Local fixtures use real canonical SQL and target-user authority with simulated token identity and user organization lookup. They prove neither live permissions nor actual sign-in.

providers is the complete stored link list for the selected user, sorted by provider name; there is no pagination or continuation. provider identifies the linked system and providerUserId is its external identity, not a Topolo user id, credential or application grant. Usernames/emails/avatar URLs can be null. Keep this identity data inside the authorized workflow.

An empty successful list means no stored links at this read, not that password, recovery or another authentication method is configured and usable. Missing target user returns NOT_FOUND instead. SQL failures return SERVER_ERROR. Bearer takes precedence over access cookies for these provider handlers.

Worked examples

These are complete raw target-handler responses, not CLI/gateway envelopes or live authorization proof. Replace synthetic identifiers using authorized discovery. Save only the reviewed input as payload.json; inspect validation and plan before executing. --confirm assumes the intended operation is approved. Storage read-back and actual sign-in outcomes require separate verification. Provider unlink does not revoke external accounts, consent or existing Auth sessions. Cookies and Bearer tokens must identify the intended principal consistently.

Self reads linked providers sorted by provider name

Input · payload.json:

{
  "userId": "usr_self"
}

CLI:

topolo actions validate app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions plan app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions call app_topolo_auth.user_oauth_providers.list --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_oauth_providers.list",
    "input": {
      "userId": "usr_self"
    }
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "OAuth providers fetched",
  "data": {
    "providers": [
      {
        "provider": "github",
        "providerUserId": "external_github_usr_self",
        "providerUsername": "fixture-usr_self",
        "providerEmail": "usr_self@example.test",
        "avatarUrl": null,
        "createdAt": 1,
        "updatedAt": 1
      },
      {
        "provider": "google",
        "providerUserId": "external_google_usr_self",
        "providerUsername": "fixture-usr_self",
        "providerEmail": "usr_self@example.test",
        "avatarUrl": null,
        "createdAt": 1,
        "updatedAt": 1
      }
    ]
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

userId identity alias supports self provider discovery

Input · payload.json:

{
  "userId": "usr_self"
}

CLI:

topolo actions validate app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions plan app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions call app_topolo_auth.user_oauth_providers.list --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_oauth_providers.list",
    "input": {
      "userId": "usr_self"
    }
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "OAuth providers fetched",
  "data": {
    "providers": [
      {
        "provider": "github",
        "providerUserId": "external_github_usr_self",
        "providerUsername": "fixture-usr_self",
        "providerEmail": "usr_self@example.test",
        "avatarUrl": null,
        "createdAt": 1,
        "updatedAt": 1
      },
      {
        "provider": "google",
        "providerUserId": "external_google_usr_self",
        "providerUsername": "fixture-usr_self",
        "providerEmail": "usr_self@example.test",
        "avatarUrl": null,
        "createdAt": 1,
        "updatedAt": 1
      }
    ]
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Administrator reads only its authorized managed user

Input · payload.json:

{
  "userId": "usr_managed"
}

CLI:

topolo actions validate app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions plan app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions call app_topolo_auth.user_oauth_providers.list --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_oauth_providers.list",
    "input": {
      "userId": "usr_managed"
    }
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "OAuth providers fetched",
  "data": {
    "providers": [
      {
        "provider": "github",
        "providerUserId": "external_github_usr_managed",
        "providerUsername": "fixture-usr_managed",
        "providerEmail": "usr_managed@example.test",
        "avatarUrl": null,
        "createdAt": 1,
        "updatedAt": 1
      }
    ]
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Input · payload.json:

{
  "userId": "usr_self"
}

CLI:

topolo actions validate app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions plan app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions call app_topolo_auth.user_oauth_providers.list --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_oauth_providers.list",
    "input": {
      "userId": "usr_self"
    }
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "OAuth providers fetched",
  "data": {
    "providers": [
      {
        "provider": "google",
        "providerUserId": "external_google_usr_self",
        "providerUsername": "fixture-usr_self",
        "providerEmail": "usr_self@example.test",
        "avatarUrl": null,
        "createdAt": 1,
        "updatedAt": 1
      }
    ]
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Empty list after removal of the sole provider does not prove alternate sign-in works

Input · payload.json:

{
  "userId": "usr_managed"
}

CLI:

topolo actions validate app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions plan app_topolo_auth.user_oauth_providers.list --data @payload.json --json
topolo actions call app_topolo_auth.user_oauth_providers.list --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.user_oauth_providers.list",
    "input": {
      "userId": "usr_managed"
    }
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "OAuth providers fetched",
  "data": {
    "providers": []
  },
  "timestamp": "2026-10-02T00:00:00.000Z"
}

Verify the result

  • Keep the exact selected Topolo user id alongside each provider. Use provider, not providerUserId, for unlink input; the external identity is not a Topolo user id.

  • Before reviewing any unlink, verify an alternate approved authentication path can sign in as the same user. An empty link list cannot prove this.

Errors and recovery

Foreign organization target is refused

Captured local refusal · HTTP 403:

{
  "input": {
    "userId": "usr_foreign"
  },
  "response": {
    "success": false,
    "error": {
      "message": "Insufficient permissions",
      "code": "FORBIDDEN",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Unknown user is a not-found identity, not an empty provider list

Captured local refusal · HTTP 404:

{
  "input": {
    "userId": "usr_missing"
  },
  "response": {
    "success": false,
    "error": {
      "message": "User not found",
      "code": "NOT_FOUND",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Anonymous provider discovery is refused

Captured local refusal · HTTP 401:

{
  "input": {
    "userId": "usr_self"
  },
  "response": {
    "success": false,
    "error": {
      "message": "Access token required",
      "code": "AUTH_ERROR",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Invalid token is the current handler server error

Captured local refusal · HTTP 500:

{
  "input": {
    "userId": "usr_self"
  },
  "response": {
    "success": false,
    "error": {
      "message": "Invalid fixture token",
      "code": "SERVER_ERROR",
      "details": null,
      "timestamp": "2026-10-02T00:00:00.000Z"
    }
  }
}

Published recovery guidance

  • AUTH_ERROR (HTTP 401): Verify the intended identity and transport. Unlock AUTH_ERROR can mean authenticated target-user authority denial; refresh only a genuinely expired token for the approved context.

  • FORBIDDEN (HTTP 403): Preserve the target-user authority denial. Use only an approved identity authorized for this exact user/organization; do not switch contexts automatically.

  • NOT_FOUND (HTTP 404): Refresh authorized user/provider discovery. Repeated unlink reports a missing link; do not create a fictitious link or infer external account deletion.

  • SERVER_ERROR (HTTP 500): Preserve the original error, verify the approved authentication and inspect current target state before reviewing any retry. Invalid-token exceptions and repository errors are both possible.

Recovery boundaries

Read-only. Preserve user-specific provider identity data within the authorized workflow and refresh discovery after a separately approved link change.

Discovery and evidence

This record belongs to app_topolo_auth. Local tests prove real canonical provider/security SQL, target-user authorization and handler responses with simulated tokens and identity lookup. They do not prove live permission, alternate sign-in, external-provider token/consent revocation, actual user login, deployment or production completion.