Skip to content
GigadriveDocs

Authentication

Give the client a credential explicitly, or let it detect one from the environment, and know which wins.

The Gigadrive Network client resolves a credential in its constructor, before it sends anything. Pass one in, or set environment variables and let the client find them.

Credentials you pass in

Four combinations are recognized, each selecting a different OAuth 2.0 flow.

Config fieldsFlowUse it for
clientId + clientSecretclient credentialsAPI keys: servers, CI, scripts
bearerTokennone, the token is sent as-isa token you already hold
clientId + refreshTokenrefresh token, against the IDPa stored user session
clientId + onAuthorizationUrlauthorization code with PKCEinteractive CLIs and desktop apps

Client credentials are the common case:

import { GigadriveClient } from '@gigadrive/sdk';

const client = new GigadriveClient({
  clientId: process.env.GIGADRIVE_CLIENT_ID,
  clientSecret: process.env.GIGADRIVE_CLIENT_SECRET,
});

const { items } = await client.applications.list();

The client id is an API key ID and the secret is the string that key returned at creation. Both come from API keys. The client posts them to https://api.gigadrive.network/oauth2/token with HTTP Basic auth, then caches the access token it gets back.

Access tokens last 300 seconds. The client refreshes 30 seconds before expiry, or earlier for shorter tokens, since the margin is capped at half the lifetime. Concurrent callers share one in-flight refresh rather than each triggering their own.

Every constructor option

OptionTypeDefault
clientIdstringGIGADRIVE_CLIENT_ID
clientSecretstringGIGADRIVE_CLIENT_SECRET
bearerTokenstringGIGADRIVE_BEARER_TOKEN
refreshTokenstringGIGADRIVE_REFRESH_TOKEN
applicationIdstringGIGADRIVE_APPLICATION_ID
baseUrlstringGIGADRIVE_API_BASE_URL, else https://api.gigadrive.network
idpIssuerUrlstringGIGADRIVE_IDP_ISSUER_URL, else https://idp.gigadrive.de
onAuthorizationUrl(url: string) => Promise<string>none, and no environment equivalent
redirectUristringurn:ietf:wg:oauth:2.0:oob
scopesstring[]offline_access openid profile email
fetchtypeof globalThis.fetchglobalThis.fetch, bound to globalThis

scopes applies to the authorization-code flow only, and it replaces the default set rather than adding to it. Requesting ['network:applications:read'] alone drops openid, profile, email and offline_access, so list the identity scopes again if you still want them. The names come from Scopes.

applicationId is not a credential. It supplies the default application for client.storage, which addresses buckets without repeating the application in every call.

Credentials detected from the environment

With no matching config field, the client walks this list and takes the first match.

OrderSourceResult
1config bearerTokenthe token, sent unchanged
2config clientId and clientSecretclient credentials
3config refreshToken and clientIdrefresh token
4config onAuthorizationUrl and clientIdauthorization code with PKCE
5GIGADRIVE_BEARER_TOKENthe token, sent unchanged
6GIGADRIVE_CLIENT_ID and GIGADRIVE_CLIENT_SECRETclient credentials
7GIGADRIVE_REFRESH_TOKEN and GIGADRIVE_CLIENT_IDrefresh token
8nothing matchedthrows AuthenticationError

Config always beats the environment, and the authorization-code flow has no environment branch: a callback is a function, so it can only be passed in code.

These are the seven variables the client reads:

VariablePurpose
GIGADRIVE_CLIENT_IDOAuth client id, which is the API key ID
GIGADRIVE_CLIENT_SECRETOAuth client secret, which is the API key secret
GIGADRIVE_BEARER_TOKENan access token you already hold, sent as-is and never refreshed
GIGADRIVE_REFRESH_TOKENrefresh token, exchanged at the IDP and rotated automatically
GIGADRIVE_IDP_ISSUER_URLissuer used for OIDC discovery in the refresh and PKCE flows
GIGADRIVE_API_BASE_URLAPI base URL, which also determines the token endpoint
GIGADRIVE_APPLICATION_IDdefault application context for client.storage

A bearer token is never renewed. When it expires, requests fail with AuthenticationError and you have to build a new client.

Inside a deployed Function

Every deployed Function gets its own OAuth client, with GIGADRIVE_CLIENT_ID, GIGADRIVE_CLIENT_SECRET and GIGADRIVE_APPLICATION_ID injected at start. Row 6 of that table picks them up, so the constructor takes no arguments:

import { GigadriveClient } from '@gigadrive/sdk';

const client = new GigadriveClient();

export async function saveAvatar(userId: string, file: Blob): Promise<string> {
  const { url } = await client.storage.upload({
    bucket: 'avatars',
    key: `avatars/${userId}.png`,
    data: file,
  });

  return url;
}

That credential is scoped to the Function's own application and carries storage, sticky-session and runtime-cache permissions only. It cannot create applications or read environment variables. OIDC federation lists the exact scope set and what the platform injects.

On your own machine

gigadrive setup links the directory to an application, provisions an application-scoped key, and writes GIGADRIVE_CLIENT_ID, GIGADRIVE_CLIENT_SECRET and GIGADRIVE_API_BASE_URL into .env.local. Pass --rotate to revoke the previous key and mint a fresh one.

That key is deliberately narrow: it grants network:env_vars:read and nothing else. For anything beyond reading configuration, create a key with the scopes you need through client.apiKeys.create, described in Resources.