AgentStack
SKILL verified Apache-2.0 Self-run

Integrate Oidc

skill-thunder-id-skills-integrate-oidc · by thunder-id

Integrate ThunderID using a generic OIDC library for frameworks without an official ThunderID SDK — Angular, SvelteKit, Python, Go, .NET, and others. Use when asked to "add ThunderID to Angular", "integrate ThunderID with SvelteKit", or when no official SDK covers the target framework or language.

No reviews yet
0 installs
4 views
0.0% view→install

Install

$ agentstack add skill-thunder-id-skills-integrate-oidc

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Integrate Oidc? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

ThunderID — Generic OIDC Integration

Assumes ThunderID is running at https://localhost:8090. If not, run /setup-thunderid first.

ThunderID is a standard OpenID Connect provider. Its discovery document is at:

https://localhost:8090/.well-known/openid-configuration

OIDC endpoints:

| Endpoint | URL | |----------|-----| | Discovery | https://localhost:8090/.well-known/openid-configuration | | Authorization | https://localhost:8090/oauth2/authorize | | Token | https://localhost:8090/oauth2/token | | Userinfo | https://localhost:8090/oauth2/userinfo | | JWKS | https://localhost:8090/oauth2/jwks | | End session | https://localhost:8090/oidc/logout |

Step 1 — Register an Application

Ask the developer to create an application in ThunderID and share the Client ID (and Client Secret for server-side apps) before continuing.

Guide them through these steps:

  1. Open https://localhost:8090/console and sign in (default: admin / secret)
  2. Navigate to Applications → New Application
  3. Fill in:
  • Name: their app name
  • Type: Single Page Application for browser apps; Web Application for server-side
  • Authorized Redirect URL: their app's callback URL
  1. Click Create and copy the Client ID (and Client Secret for server-side apps)

Once they paste the values, use them in all subsequent steps. Do not use placeholders — wait for the real values.


Angular — oidc-client-ts

npm install oidc-client-ts

Create src/auth.ts:

import { UserManager, WebStorageStateStore } from 'oidc-client-ts'

export const userManager = new UserManager({
  authority: 'https://localhost:8090',
  client_id: '',
  redirect_uri: `${window.location.origin}/callback`,
  post_logout_redirect_uri: `${window.location.origin}`,
  response_type: 'code',
  scope: 'openid profile email',
  userStore: new WebStorageStateStore({ store: window.localStorage }),
})

export const signIn = () => userManager.signinRedirect()
export const signOut = () => userManager.signoutRedirect()
export const getUser = () => userManager.getUser()

Callback handler at the /callback route:

import { userManager } from './auth'
await userManager.signinRedirectCallback()
window.location.replace('/')

Route guard:

import { inject } from '@angular/core'
import { CanActivateFn, Router } from '@angular/router'
import { getUser } from './auth'

export const authGuard: CanActivateFn = async () => {
  const user = await getUser()
  if (!user || user.expired) {
    inject(Router).navigate(['/'])
    return false
  }
  return true
}

SvelteKit — Auth.js

npm install @auth/sveltekit

src/auth.ts:

import { SvelteKitAuth } from '@auth/sveltekit'

export const { handle, signIn, signOut } = SvelteKitAuth({
  providers: [
    {
      id: 'thunderid',
      name: 'ThunderID',
      type: 'oidc',
      issuer: 'https://localhost:8090',
      clientId: '',
      clientSecret: '',
    },
  ],
})

src/hooks.server.ts:

export { handle } from './auth'

Protect a route in +page.server.ts:

import { redirect } from '@sveltejs/kit'
import type { PageServerLoad } from './$types'

export const load: PageServerLoad = async (event) => {
  const session = await event.locals.auth()
  if (!session) throw redirect(303, '/')
  return { session }
}

Sign-in / sign-out in a Svelte component:


  import { signIn, signOut } from '@auth/sveltekit/client'
  import { page } from '$app/stores'

{#if $page.data.session}
   signOut()}>Sign Out
  Signed in as {$page.data.session.user?.email}
{:else}
   signIn('thunderid')}>Sign In
{/if}

Python — authlib

pip install authlib httpx
from authlib.integrations.httpx_client import AsyncOAuth2Client

client = AsyncOAuth2Client(
    client_id='',
    client_secret='',
    redirect_uri='http://localhost:8000/callback',
)

# Discover endpoints
metadata = await client.load_server_metadata('https://localhost:8090/.well-known/openid-configuration')

# Start login
uri, state = client.create_authorization_url(metadata['authorization_endpoint'], scope='openid profile email')

# In the callback handler
token = await client.fetch_token(metadata['token_endpoint'], authorization_response=str(request.url))
userinfo = await client.get(metadata['userinfo_endpoint'])

Go — coreos/go-oidc

go get github.com/coreos/go-oidc/v3/oidc golang.org/x/oauth2
provider, err := oidc.NewProvider(ctx, "https://localhost:8090")

config := oauth2.Config{
    ClientID:     "",
    ClientSecret: "",
    RedirectURL:  "http://localhost:8080/callback",
    Endpoint:     provider.Endpoint(),
    Scopes:       []string{oidc.ScopeOpenID, "profile", "email"},
}

// Start login
http.Redirect(w, r, config.AuthCodeURL(state), http.StatusFound)

// In /callback
token, err := config.Exchange(ctx, r.URL.Query().Get("code"))
idToken, err := provider.Verifier(&oidc.Config{ClientID: ""}).Verify(ctx, token.Extra("id_token").(string))

var claims struct {
    Email string `json:"email"`
    Name  string `json:"name"`
}
idToken.Claims(&claims)

Troubleshooting

Certificate error — For browsers: visit https://localhost:8090 and accept the warning. For Node.js: add NODE_TLS_REJECT_UNAUTHORIZED=0 to .env.local (dev only). For Python: pass verify=False to the HTTP client (dev only). For Go: configure a custom TLS client.

CORS error — Ensure the redirect URI registered in the ThunderID console exactly matches the one used in code, including trailing slashes.

invalid_client — Double-check the Client ID and Client Secret.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.