Skip to main content

Okta SSO Setup

This guide walks you through configuring Okta as an OIDC identity provider for SigmaShake Fleet. After setup, your team members can sign into the Fleet dashboard and authenticate the ssg CLI using their Okta credentials.

Estimated Time

This setup takes approximately 15 minutes.

Step 1: Create an Okta Application

  1. Sign in to your Okta Admin Console
  2. Navigate to Applications → Applications in the left sidebar
  3. Click Create App Integration
  4. Select:
    • Sign-in method: OIDC - OpenID Connect
    • Application type: Web Application
  5. Click Next

Step 2: Configure the Application

Fill in the following settings:

General Settings

FieldValue
App integration nameSigmaShake Fleet
Logo(optional) Upload the SigmaShake logo

Sign-in Redirect URIs

Add all of the following redirect URIs:

# Fleet dashboard — replace {YOUR_ORG_ID} and {YOUR_SUBDOMAIN}
https://{YOUR_SUBDOMAIN}.fleet.sigmashake.com/api/v1/orgs/{YOUR_ORG_ID}/sso/oidc/callback

# CLI local callback — required for `ssg auth login --sso`
http://127.0.0.1:8399/callback
Exact match required

Okta requires exact URI matches. The org ID must follow the format org_<slug> (e.g., org_sigmashake). Find your org ID in the Fleet dashboard or by running:

ssg fleet status

Example for sigmashake subdomain:

https://sigmashake.fleet.sigmashake.com/api/v1/orgs/org_sigmashake/sso/oidc/callback
http://127.0.0.1:8399/callback

Sign-out Redirect URIs

https://{YOUR_SUBDOMAIN}.fleet.sigmashake.com/

Controlled Access

Choose one of:

  • Allow everyone in your organization to access — Recommended for smaller orgs
  • Limit access to selected groups — For fine-grained control

Click Save.

Step 3: Collect Okta Credentials

After saving, you'll be on the app's General tab. Copy these values:

FieldWhere to find it
Client IDGeneral tab → Client Credentials section
Client SecretGeneral tab → Client Credentials → click Edit to reveal
Issuer URLNavigate to Security → API → copy the Issuer URI for your authorization server
Issuer URL Format

The issuer URL for Okta typically follows this pattern:

https://your-domain.okta.com/oauth2/default

If you're using a custom authorization server, use that issuer URL instead.

Step 4: Configure Authorization Server Access Policy

Required — without this, logins will fail with "Policy evaluation failed"

The Okta authorization server must have an access policy that permits your OIDC app.

  1. Go to Security → API → Authorization Servers
  2. Click on default (or your custom authorization server)
  3. Go to the Access Policies tab
  4. If no policy exists, click Add Policy and name it SigmaShake Fleet
  5. Click the ▶ next to your policy → Add Rule
  6. Configure the rule:
    • Rule Name: Allow SigmaShake Fleet
    • Grant type: ☑ Authorization Code
    • User is: Any user assigned the app (or specific groups)
    • Scopes requested: Any scopes (or select openid, email, profile)
  7. Click Create Rule, then Save

Step 5: Assign Users to the Application

Before users can authenticate:

  1. Go to your Okta app's Assignments tab
  2. Click Assign → Assign to People (or Assign to Groups)
  3. Select the users/groups who should have fleet access
  4. Click Save and Go Back
Fleet Membership Required

Users must also be members of your SigmaShake Fleet organization. Add members via the Fleet dashboard (Agents → Members) or via the Fleet API:

curl -X POST https://{YOUR_SUBDOMAIN}.fleet.sigmashake.com/api/v1/orgs/{YOUR_ORG_ID}/members \
-H "Authorization: Bearer {SESSION_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user@company.com",
"role": "member"
}'

Available roles: org_admin, policy_author, auditor, member

Step 6: Configure SigmaShake Fleet

Run the following command to configure OIDC SSO on your SigmaShake Fleet organization:

curl -X PUT https://{YOUR_SUBDOMAIN}.fleet.sigmashake.com/api/v1/orgs/{YOUR_ORG_ID}/sso/config \
-H "Authorization: Bearer {YOUR_SESSION_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"provider": "oidc",
"issuer_url": "https://your-domain.okta.com/oauth2/default",
"client_id": "YOUR_OKTA_CLIENT_ID",
"client_secret": "YOUR_OKTA_CLIENT_SECRET"
}'

You should receive a success response:

{"ok": true, "provider": "oidc", "org_id": "your_org_id"}

Step 7: Configure ssg CLI SSO Login

Team members can authenticate the ssg CLI using their Okta credentials:

ssg auth login --sso \
--issuer=https://your-domain.okta.com/oauth2/default \
--client-id=YOUR_OKTA_CLIENT_ID

Or interactively:

ssg auth login --sso
# Follow the prompts to enter your Issuer URL and Client ID

This opens your browser for Okta login and captures the callback on http://127.0.0.1:8399/callback.

Persist SSO Config

To avoid entering your IdP details every time, set environment variables:

export SSG_SSO_ISSUER=https://your-domain.okta.com/oauth2/default
export SSG_SSO_CLIENT_ID=YOUR_OKTA_CLIENT_ID
# Then just run:
ssg auth login --sso

Or add your fleet org's SSO config and it will be detected automatically from ~/.sigmashake/fleet.toml.

Step 8: Test the Login

Fleet Dashboard

Open your browser and navigate to:

https://{YOUR_SUBDOMAIN}.fleet.sigmashake.com/api/v1/orgs/{YOUR_ORG_ID}/sso/oidc/login

This should:

  1. Redirect you to the Okta login page
  2. After authentication, redirect back to the Fleet agents dashboard
  3. Set a session cookie (ssg_fleet_session) valid for 8 hours

CLI

After ssg auth login --sso completes:

ssg auth status # Confirm SSO authentication
ssg doctor # Verify license tier is ENTERPRISE (not Free)

Troubleshooting

"The 'redirect_uri' parameter must be a Login redirect URI"

The callback URI is not registered in your Okta app.

  • Verify you added both URIs from Step 2
  • For the fleet dashboard URI, confirm the {YOUR_ORG_ID} matches exactly (e.g., org_sigmashake)
  • For CLI login, confirm http://127.0.0.1:8399/callback is in the list

"Policy evaluation failed" / access_denied

The Okta authorization server has no access policy rule that permits your app.

  • Follow Step 4 to create an access policy rule for the default authorization server
  • Confirm the rule includes Authorization Code grant type
  • Confirm the user is assigned to the application (Step 5)

"OIDC SSO is not configured for this organization"

  • Verify the PUT /sso/config call returned {"ok": true}
  • Check that provider is set to "oidc" (not "saml")

"Invalid or expired state parameter (possible CSRF)"

  • The login flow timed out (state tokens expire after 10 minutes)
  • Try again by navigating to the login URL

"User is not a member of this organization"

  • The user's email from Okta must match an email in SigmaShake Fleet
  • Add the user as a fleet member first (see Step 5)

ssg doctor shows "Free tier" after SSO login

The ssg CLI resolves your license by matching your SSO email to a SigmaShake account. Ensure:

  1. Your SigmaShake organization has an active Enterprise subscription
  2. Your email domain is registered with your fleet org's SSO domain:
    # Set SSO domain for your org (admin only)
    curl -X PATCH https://{SUBDOMAIN}.fleet.sigmashake.com/api/v1/orgs/{ORG_ID} \
    -H "Authorization: Bearer {TOKEN}" \
    -d '{"sso_domain": "yourdomain.com"}'
  3. Run ssg auth refresh to force a license re-check after the domain is set

"OIDC token exchange failed" (502)

  • Verify your Client Secret is correct in the Fleet SSO config
  • Ensure the Redirect URI in Okta exactly matches the callback URI
  • Check that your Okta authorization server is active

"id_token signature verification failed"

  • SigmaShake verifies signatures using JWKS — ensure your Okta authorization server publishes a valid jwks_uri in its discovery document
  • JWKS is cached for 1 hour; if you rotated keys, wait up to 1 hour for the cache to refresh

Architecture

User Browser SigmaShake Fleet Okta
│ │ │
│──── GET /sso/oidc/login ────▶│ │
│ │── store state in KV ────▶│
│◄─── 302 Redirect ───────────│ │
│ │ │
│──── Okta login page ────────────────────────────────────▶│
│◄─── 302 + code + state ─────────────────────────────────│
│ │ │
│──── GET /sso/oidc/callback ─▶│ │
│ │── validate state ───────▶│
│ │── exchange code ─────────▶│
│ │◄── id_token ─────────────│
│ │── verify JWKS sig ──────▶│
│ │── check membership ─────▶│
│ │── create session ───────▶│
│◄─── 302 /agents ────────────│ │
│ + Set-Cookie │ │

CLI (ssg auth login --sso) SigmaShake Accounts API Okta
│ │ │
│── open browser ─────────────────────────────────────────▶│
│◄── 302 + code + state ──────────────────────────────────│
│◄── http://127.0.0.1:8399/callback?code=...──────────────│
│── exchange code (PKCE) ──────▶ │
│◄── id_token + access_token ──│ │
│── GET /api/license ──────────▶ │
│ X-Auth-Method: sso │ │
│ X-SSO-Email: user@corp.com │ │
│◄── license JWT (ENTERPRISE) ─│ │

Security Notes

  • Client secrets are stored encrypted in the SigmaShake database and never exposed via the API
  • State parameters are stored in KV with a 10-minute TTL to prevent CSRF attacks
  • ID tokens are verified using JWKS (fetched from Okta's discovery endpoint, cached 1hr)
  • Sessions are 8-hour HttpOnly, Secure, SameSite=Lax cookies
  • CLI tokens are stored in ~/.sigmashake/hosts.toml (mode 0600, never committed to git)
  • License resolution for SSO users matches email → SigmaShake account or org email domain
  • All traffic is HTTPS-only with HSTS enforced