This guide walks through setting up OAuth2/OIDC authentication with popular identity providers.
To use epithet auth oidc, you need to create an OAuth2 application in your identity provider's console. This gives you a client ID and optionally a client secret to use with epithet.
Important: Epithet uses PKCE (Proof Key for Code Exchange), so the client secret is optional. For most providers, you can create a "desktop app" or "native app" which doesn't require a client secret.
- Go to Google Cloud Console
- Select or create a project
- Navigate to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Choose Application type - see options below
- Enter a name (e.g., "Epithet SSH CA")
- Click Create
Application Type Options:
Option A: Universal Windows Platform (UWP) (Recommended - No client secret needed)
- Choose "Universal Windows Platform (UWP)"
- Fill in Store package ID with any valid string (e.g., "epithet-ssh-ca")
- Advantage: Works with PKCE only, no client secret required
- Note: Despite the name, this works for any CLI tool on any platform
Option B: Desktop app (Requires client secret)
- Choose "Desktop app"
- Advantage: Standard Desktop app type
- Disadvantage: Google requires client secret even with PKCE
- You'll need to include
--client-secretin your epithet configuration
Both app types automatically accept http://localhost with any port. No manual configuration needed!
You'll see a dialog with:
- Client ID: Something like
123456-abc.apps.googleusercontent.com - Client secret:
- UWP apps: Not needed (can ignore)
- Desktop apps: Required - note this value
For UWP apps (no client secret needed):
epithet agent \
--ca-url https://ca.example.com \
--auth "epithet auth oidc \
--issuer https://accounts.google.com \
--client-id YOUR_CLIENT_ID.apps.googleusercontent.com"For Desktop apps (client secret required):
epithet agent \
--ca-url https://ca.example.com \
--auth "epithet auth oidc \
--issuer https://accounts.google.com \
--client-id YOUR_CLIENT_ID.apps.googleusercontent.com \
--client-secret YOUR_CLIENT_SECRET"Or in a config file (~/.epithet/config.yaml):
UWP apps:
agent:
ca-url: https://ca.example.com
auth: "epithet auth oidc --issuer https://accounts.google.com --client-id YOUR_CLIENT_ID.apps.googleusercontent.com"Desktop apps:
agent:
ca-url: https://ca.example.com
auth: "epithet auth oidc --issuer https://accounts.google.com --client-id YOUR_CLIENT_ID.apps.googleusercontent.com --client-secret YOUR_CLIENT_SECRET"When you first connect via SSH:
- Your browser will open automatically
- You may see "This app isn't verified" (normal for personal OAuth apps)
- Click "Advanced" → "Go to Epithet SSH CA (unsafe)"
- Grant the requested permissions
- Browser will show "Authentication successful"
- Return to your terminal - SSH connection proceeds
Subsequent connections use the refresh token automatically (no browser needed).
If you're using a shared OAuth app or want to skip the "unverified" warning:
- Go to Google Admin Console
- Navigate to Security → API controls → App access control
- Click Configure under "Trusted apps"
- Add your OAuth client ID
- Users in your domain won't see the warning
Default scopes (openid,profile,email) are usually sufficient. Your CA server will receive the ID token for validation.
If your CA needs additional Google APIs, add them to --scopes:
--scopes openid,profile,email,https://www.googleapis.com/auth/admin.directory.user.readonlyNote: Additional scopes may require app verification if you exceed 100 users.
- Log in to your Okta Admin Console
- Navigate to Applications → Applications
- Click Create App Integration
- Choose OIDC - OpenID Connect
- Choose Application type: Native Application
- Click Next
- App integration name: Enter "Epithet SSH CA"
- Grant type: Check Authorization Code and Refresh Token
- Sign-in redirect URIs: Add
http://localhost:8080/callback- Okta doesn't support wildcard ports, so also add:
http://localhost:8081/callbackhttp://localhost:8082/callback- (epithet will try these ports in order)
- Sign-out redirect URIs: Leave empty
- Controlled access: Choose appropriate assignment (e.g., "Allow everyone in your organization to access")
- Click Save
After creating the app:
- Client ID: Copy this value
- Client secret: Not needed (PKCE handles authentication)
Your Okta issuer URL depends on your authorization server:
- Default:
https://your-domain.okta.com/oauth2/default - Custom:
https://your-domain.okta.com/oauth2/your-auth-server
To verify:
- Go to Security → API → Authorization Servers
- Find your authorization server
- Copy the Issuer URI
epithet agent \
--ca-url https://ca.example.com \
--auth "epithet auth oidc \
--issuer https://your-domain.okta.com/oauth2/default \
--client-id YOUR_CLIENT_ID"Default scopes work for most cases. Okta supports:
openid(required)profile(user profile info)email(email address)offline_access(refresh tokens - automatically included by epithet)
Custom scopes can be defined in your authorization server configuration.
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click New registration
- Enter Name: "Epithet SSH CA"
- Choose Supported account types:
- Single tenant: Only your organization
- Multi-tenant: Any Azure AD organization
- Redirect URI: Select Public client/native (mobile & desktop), enter
http://localhost - Click Register
- In your app, go to Authentication
- Under Advanced settings → Allow public client flows: Select Yes
- Click Save
- Application (client) ID: Copy this from the Overview page
- Directory (tenant) ID: Also from the Overview page
- Client secret: Not needed for public clients
epithet agent \
--ca-url https://ca.example.com \
--auth "epithet auth oidc \
--issuer https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0 \
--client-id YOUR_CLIENT_ID"Replace:
YOUR_TENANT_IDwith your Directory (tenant) IDYOUR_CLIENT_IDwith your Application (client) ID
- Specific tenant: Use your tenant ID (e.g.,
12345678-1234-1234-1234-123456789012) - Organizations: Use
organizations(any Azure AD tenant) - Common: Use
common(any Azure AD or personal Microsoft account)
Default scopes work for most cases. Azure AD supports:
openid(required)profile(user profile info)email(email address)offline_access(refresh tokens - automatically included by epithet)
If your provider supports OIDC discovery (most modern providers do), you can use the generic configuration:
Follow your provider's documentation to create an OAuth2 application with:
- Application type: Native, Desktop, or Public Client
- Grant type: Authorization Code
- PKCE: Enabled (required)
- Redirect URI:
http://localhost:8080/callback(or wildcard if supported)
Most providers expose OIDC discovery at:
https://your-provider.com/.well-known/openid-configuration
The issuer URL is usually the base URL (without /.well-known/...).
epithet agent \
--ca-url https://ca.example.com \
--auth "epithet auth oidc \
--issuer https://your-provider.com \
--client-id YOUR_CLIENT_ID \
--scopes openid,profile,email"You can test authentication without running the full broker:
# Run the auth plugin manually
echo "" | epithet auth oidc \
--issuer https://accounts.google.com \
--client-id YOUR_CLIENT_ID \
3>&1 1>/dev/null
# This should:
# 1. Open your browser
# 2. Prompt for authentication
# 3. Output state to fd 3 (which we redirect to stdout)- Check that your
--issuerURL is correct - Verify your provider supports OIDC discovery
- Try accessing
{issuer}/.well-known/openid-configurationin a browser
- Verify your
--client-idis correct - Check that the OAuth app is enabled in your provider
- Ensure redirect URI is configured correctly (
http://localhostorhttp://localhost:8080/callback)
- "redirect_uri_mismatch": Add
http://localhost:8080/callback(or your configured port) to your OAuth app's redirect URIs - "invalid_client": Double-check your client ID
- "unauthorized_client": Your OAuth app may not be configured for authorization code flow or PKCE
- Refresh token may have expired (Google: 6 months inactive)
- OAuth app may have been disabled or deleted
- User may have revoked access
- Solution: Delete broker state and re-authenticate (or restart broker)
This is normal for personal OAuth apps. Options:
- Click "Advanced" → "Go to {app name} (unsafe)" to proceed
- Have your Google Workspace admin allowlist the app
- Submit your app for Google verification (if you have many users)
- Authentication overview - How auth plugins work
- Example configurations - Complete working examples