neosourceDocs
Search docs

Widen the granted scope of an already-linked provider

POST/api/auth/oauth/{provider}/elevate

elevateOauthScope

Session-authenticated caller only (no sudo). Re-runs the OAuth handshake for a provider ALREADY linked to the account to widen its granted scope — e.g. add `repo` for private-repo import (set `requested_scope: "repo"`). Refuses if the provider isn't linked yet (use the sudo-gated `/link` flow to add a new identity), and the **callback refuses any provider account this neosource account has not already linked** — elevation widens an existing link, it never attaches a new identity. The provider's own consent screen still gates the grant, so this can't silently widen access. **Every bearer access token — including unrestricted and legacy tokens — is refused** with `403 { error: "forbidden" }` before the handshake starts (ADR 0069 §6): the handshake ends in a session cookie, which carries no token grant.

Requires authentication using a session cookie — see tokens and scopes.

curl

curl -X POST 'https://neosource.dev/api/auth/oauth/PROVIDER/elevate' \
  -b 'ns_session=$NEOSOURCE_SESSION' \
  -H 'Content-Type: application/json' \
  -d '{"intent":"string"}'

fetch

fetch("https://neosource.dev/api/auth/oauth/PROVIDER/elevate", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  credentials: "include",
  body: JSON.stringify({"intent":"string"}),
});

Path parameters

providerrequired

One of: `github`. Extend as more providers come online.

string

Request bodyrequired

application/json

OAuthStartRequest

object

claim_handle

string | null

`neosource` handle the user is trying to claim; required when `intent = "claim_handle"`. The callback enforces the provider login matches this value (case-insensitive).

intentrequired

OAuthIntent

string

"login""link""claim_handle"

requested_scope
one of
  • null

  • OAuthScope

    string

    How much provider access an OAuth handshake should request. Drives incremental authorization (see `plans/github-onboarding-tiers.md`): login asks for the minimum, and elevated tiers are requested only when the user opts into the feature that needs them. The provider client maps each tier onto the concrete provider scope string.

    "minimal""repo""repo_and_deploy_key"

return_to

string | null

Internal path the SPA wants to land on after the callback. Only values starting with `/` (and not `//`) are honoured.

additional propertiesnot allowed

Responses

200Redirect URL

application/json

OAuthStartResponse

object

redirect_urlrequired

string

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bad Request — one of: invalid_input
  • 401Authentication required
  • 403Forbidden — one of: forbidden
  • 429Rate limited — retry after the `Retry-After` header
  • 500Internal server error
  • 502Bad Gateway — one of: upstream
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget