Skip to content

Authentication

Skynet auth is OAuth 2.0 against the auth service at apps/auth/. The public API trusts tokens issued by auth; the same tokens authorize HTTP requests and WebSocket connections.

Grant types supported

The auth service implements only the authorization_code grant. Refresh is handled separately at /oauth/token/refresh rather than through the refresh_token grant type. There is no client_credentials, password, or implicit flow.

If you're building a confidential server-side integration without an interactive user — what you'd usually do with client_credentials — the current path is to register a first-party OAuth client and run the authorization-code flow once as a known user, then store the refresh token. This is workable but not what client_credentials is normally for; flag if you need a cleaner flow.

Endpoints

Step Method + path
Authorization GET https://auth.skynetgo.org/oauth/authorize
Token exchange POST https://api.skynetgo.org/oauth/token
Token refresh POST https://api.skynetgo.org/oauth/token/refresh

The authorization endpoint lives on the auth service; the token and refresh endpoints are served by the public API (apps/public-api/public_api/routers/oauth.py).

PKCE is supported and recommended for public clients — the OAuthAuthorizationCode record stores the PKCE challenge for verification at token exchange.

OAuth client registration

OAuth clients live in the OAuthClient table. Each client has:

  • A client ID and (for confidential clients) a client secret.
  • A list of redirect_uris the auth server will permit.
  • A list of allowed_scopes — the scopes this client may request.
  • An is_first_party flag — first-party clients (the official web app, SkyNode) get streamlined consent screens; third-party clients always prompt for explicit consent.

To register an integration as an OAuth client, contact the Skynet team. There is no public self-service client registration today.

Scopes

Scopes are not drawn from a predefined enum — they're stored as strings on each client's allowed_scopes array. The vocabulary is defined by the API endpoints that check for scopes, not centrally.

Common conventions you'll see:

  • read — read-only access to user-visible data.
  • write — read + create/edit user-visible data.
  • Resource-prefixed scopes (e.g. observations:write) when a client needs narrower authority than write would imply.

When you register your client, the Skynet team will work out the appropriate scope set with you. If you find an endpoint your token won't reach, the scope is the most likely cause.

Tokens

All tokens — access, refresh, and the bearer tokens SkyNode installations use — live in a unified Token table with a token_type discriminator. A given token is bound to either a user or a SkyNode installation (enforced by a check constraint), never both, and carries an optional client_id pointing back at the OAuth client that minted it.

This unification means:

  • There is no separate "personal API token" resource that lives outside OAuth. Every integration uses an OAuth-issued token.
  • Token introspection works the same way for human users and SkyNode installs.

Using an access token

Pass it as a Bearer token in the Authorization header:

GET /v1/observations HTTP/1.1
Host: api.skynetgo.org
Authorization: Bearer <access-token>

For WebSocket connections, pass the token via query string, the Authorization header, or a session cookie — see WebSocket protocol.

Refreshing

When the access token expires, exchange the refresh token at:

POST /oauth/token/refresh HTTP/1.1
Host: api.skynetgo.org
Content-Type: application/x-www-form-urlencoded

refresh_token=<refresh-token>&client_id=<client-id>

The response shape is the standard OAuth token-response JSON (access_token, refresh_token, expires_in, token_type). Use the new refresh token going forward — refresh tokens may rotate.

SkyNode installation tokens

SkyNode installations are paired with a telescope or observatory via the same authorization-code flow (with the user signed in as someone with appropriate authority). After pairing, the install holds a long-lived refresh token tied to a SkyNodeInstallation record; SkyNode rotates its access token automatically using the same /oauth/token/refresh endpoint.

For owners managing SkyNode installs, see SkyNode → Installation.

Session cookies (web app)

The web app uses a session cookie (skynet_session) on top of OAuth — the OAuth token round-trip happens on first login, and the session cookie carries the user identity from then on. For API integrations, use bearer tokens rather than trying to drive the session cookie; cookies are a UX detail of the web app.

Things to confirm before going live

  • Test against the next environment before production.
  • Verify your client's scopes cover every endpoint your integration hits. The fastest way is to call each endpoint once and see what rejects.
  • Implement refresh-token rotation handling — when refresh returns a new refresh token, replace the old one immediately.
  • Decide where the tokens live. Treat them as secrets.