oauth - OAuth authentication in SLICC

SYNOPSIS

oauth-token <provider>          Get an access token for a provider
oauth-token --provider <id>     Same, using flag form
oauth-token                      Get token for the currently selected provider
oauth-token --list               List OAuth providers with status
oauth-token --help               Show help

DESCRIPTION

The oauth-token command retrieves an OAuth access token for a given provider. If a valid (non-expired) token already exists, it is returned immediately. If no token exists or the current token has expired, the OAuth login flow is triggered automatically — a browser tab opens for the user to authenticate. The raw access token is printed to stdout on success.

When called with no arguments, oauth-token uses the currently selected provider. If the selected provider is not an OAuth provider, it falls back to the first available OAuth provider. Use oauth-token --list to see which providers are configured and their login status.

USAGE IN SHELL PIPELINES

Use command substitution to inject tokens into HTTP requests:

curl -H "Authorization: Bearer $(oauth-token adobe)" https://api.example.com/data
curl -H "Authorization: Bearer $(oauth-token github)" https://api.github.com/user

The token is printed to stdout with a trailing newline, so $(oauth-token <provider>) captures it cleanly.

USAGE IN .jsh SCRIPTS

In .jsh scripts, use exec() to call oauth-token:

const result = await exec('oauth-token adobe');
if (result.exitCode !== 0) {
  console.error('OAuth failed:', result.stderr);
  process.exit(1);
}
const token = result.stdout.trim();

const resp = await fetch('https://api.example.com/data', {
  headers: { 'Authorization': `Bearer ${token}` }
});
const data = await resp.json();
console.log(JSON.stringify(data, null, 2));

PROVIDER-BASED AUTH

Each OAuth provider (adobe, github, etc.) has its own configuration defined as a ProviderConfig with isOAuth: true. The provider handles provider-specific logic: building the authorize URL, extracting the token from the redirect URL, and fetching user profile information. SLICC provides the transport layer — opening the browser window and returning the redirect URL.

Supported providers depend on what is configured in the deployment. Use oauth-token --list to see available providers and their status (logged in, expired, or no token).

LOGIN FLOW

When oauth-token needs a new token, it calls the provider's onOAuthLogin(launcher, onSuccess) callback. The flow works as follows:

The createOAuthLauncher() factory in providers/oauth-service.ts automatically selects the correct transport for the current runtime. Both modes time out after 2 minutes.

TOKEN STORAGE AND REFRESH

Tokens are persisted via saveOAuthAccount() in provider settings. Each account stores the access token, expiration time, and optional user name. When oauth-token is called, it checks for a stored non-expired token first. If the token is expired, the full login flow is re-triggered. Providers that support token refresh handle it within their onOAuthLogin implementation.

PROVIDER MERGE LAYERS

Model capabilities are resolved through a three-layer merge:

Fields include api (anthropic or openai), context_window, max_tokens, reasoning, and input modalities.

EXTERNAL PROVIDERS

Custom providers are added by placing .ts files in packages/webapp/providers/. Each file exports a config: ProviderConfig and optionally a register() function for custom stream functions. External providers are always included (never filtered by build config) and are typically used for corporate SSO or API proxies.

ERROR HANDLING

SEE ALSO

jsh(1), skill(1), float(1)