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_uristhe auth server will permit. - A list of
allowed_scopes— the scopes this client may request. - An
is_first_partyflag — 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 thanwritewould 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
nextenvironment 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.