Integration guide

LycianAuth is a standard OpenID Provider. Apps integrate with the Authorization Code flow and PKCE, then verify EdDSA-signed JWTs locally. Any OIDC client library works; the SDKs below are optional.

Issuer · https://auth.lycian.app

Core concepts

Client types

When you register an app, you choose how it will authenticate. Pick based on where your code runs.

If you're not sure: a React/Vue/mobile app is public; a Node/Go/Rails backend is confidential.

1 · Send the user to log in

Redirect the browser to the authorization endpoint with a PKCE challenge:

GET https://auth.lycian.app/authorize
  ?client_id=o-pt-pt
  &redirect_uri=https://o-pt-pt.com/callback
  &response_type=code
  &scope=openid email profile offline_access
  &state=RANDOM_STRING
  &code_challenge=BASE64URL(SHA256(verifier))
  &code_challenge_method=S256

The user lands on the hosted login page, signs in, and is redirected back to redirect_uri?code=...&state=.... Verify that state matches what you sent.

2 · Exchange the code for tokens

From your app, exchange the authorization code:

POST https://auth.lycian.app/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=THE_CODE
&redirect_uri=https://o-pt-pt.com/callback
&client_id=o-pt-pt
&code_verifier=THE_VERIFIER      # public clients (PKCE)
# confidential clients also send their client secret
# (HTTP Basic auth, or client_secret_post)

You receive an access_token (a JWT), an id_token, a refresh_token, and expires_in.

3 · Verify access tokens — Go

On your API, verify the JWT on each request. The Go SDK wraps discovery, key fetching and validation:

import lycianauth "github.com/lycianapp/lycianauth/sdk/go"

verifier, _ := lycianauth.NewVerifier(ctx, "https://auth.lycian.app", "o-pt-pt")
mux.Handle("/api/", verifier.Middleware(apiHandler))

// inside a protected handler:
claims, _ := lycianauth.ClaimsFrom(r.Context())
userID := claims.Subject

The middleware checks the signature against the published keys and confirms the issuer, audience and expiry. No call back to LycianAuth is needed per request.

4 · Browser — TypeScript

For single-page apps, the browser SDK handles the PKCE dance:

import { LycianAuth } from "./lycianauth";

const client = new LycianAuth({
  issuer: "https://auth.lycian.app",
  clientId: "o-pt-pt",
  redirectUri: location.origin + "/callback",
});

await client.login();                          // on your sign-in button
const tokens = await client.handleCallback();  // on your /callback route

Refresh & logout

Access tokens last 15 minutes; refresh tokens last 30 days.

Endpoint reference