Skip to main content
CoreSDK
Authentication

OAuth 2.0 & OIDC

Integrate OAuth 2.0 authorization code flow, PKCE, and token exchange with CoreSDK.

OAuth 2.0 & OIDC

Phase note. This feature ships in Phase 2. The API shown is the planned surface.

CoreSDK will support the OAuth 2.0 authorization code flow with optional PKCE, OIDC discovery, and automatic token refresh. Configure your IdP once — CoreSDK handles redirects, token exchange, and session hydration.

In Phase 1, CoreSDK validates tokens already issued by your OAuth/OIDC provider using validate_token. See JWT Authentication for the Phase 1 API.

Token validation (Phase 1)

Point CoreSDK at your IdP's JWKS endpoint and validate inbound tokens:

use coresdk_engine::{Engine, auth::decision::AuthRequest};

// CORESDK_JWKS_URL=https://accounts.google.com/.well-known/openid-configuration
let engine = Engine::from_env()?;

let decision = engine.auth().authorize(AuthRequest {
    token: bearer_token,
    ..Default::default()
})?;

if !decision.allowed {
    return Err(ProblemDetail::unauthorized("invalid token"));
}
// decision.claims contains the verified JWT claims
from coresdk import CoreSDKClient, SDKConfig

# Set CORESDK_JWKS_URL=https://accounts.google.com/.well-known/openid-configuration
_sdk = CoreSDKClient(SDKConfig.from_env())

decision = _sdk.validate_token(bearer_token)
if not decision.allowed:
    raise Exception(decision.reason)
# decision.claims contains the verified JWT payload

Authorization code flow (Phase 2)

Redirect users to your IdP's authorization endpoint, then exchange the returned code for tokens.

use coresdk_engine::{Engine, EngineConfig};

let engine = Engine::new(EngineConfig {
    tenant_id: "acme".to_string(),
    oauth_client_id: Some("client_abc123".to_string()),
    oauth_client_secret: Some("secret_xyz".to_string()),
    oauth_redirect_uri: Some("https://app.acme.com/auth/callback".to_string()),
    oauth_scopes: vec!["openid".to_string(), "email".to_string(), "profile".to_string()],
    ..Default::default()
})?;

// Generate authorization URL
let auth_url = engine.oauth().authorization_url()
    .state("random-csrf-token")
    .build();

// In your callback handler
let tokens = engine.oauth().exchange_code(code, state).await?;
from coresdk import CoreSDKClient, SDKConfig

_sdk = CoreSDKClient(SDKConfig(
    sidecar_addr="http://127.0.0.1:7233",
    tenant_id="acme",
    service_name="my-app",
))

# Generate authorization URL
auth_url = _sdk.oauth().authorization_url(state="random-csrf-token")

# In your callback handler
tokens = await _sdk.oauth().exchange_code(code=code, state=state)
// Phase 2 — Go SDK ships in Phase 2.
import sdk "github.com/coresdk-dev/sdk-go"

s := sdk.New(sdk.Config{
    SidecarAddr:       "http://127.0.0.1:7233",
    TenantID:          "acme",
    OAuthClientID:     "client_abc123",
    OAuthClientSecret: "secret_xyz",
    OAuthRedirectURI:  "https://app.acme.com/auth/callback",
    OAuthScopes:       []string{"openid", "email", "profile"},
})

authURL := s.OAuth().AuthorizationURL(sdk.AuthURLOptions{State: "random-csrf-token"})
tokens, err := s.OAuth().ExchangeCode(ctx, code, state)
// Phase 2 — TypeScript SDK ships in Phase 2.
import { CoreSDKClient } from "@coresdk/node";

const sdk = new CoreSDKClient({
  sidecarAddr: "http://127.0.0.1:7233",
  tenantId: "acme",
  oauth: {
    clientId: "client_abc123",
    clientSecret: "secret_xyz",
    redirectUri: "https://app.acme.com/auth/callback",
    scopes: ["openid", "email", "profile"],
  },
});

const authUrl = sdk.oauth().authorizationUrl({ state: "random-csrf-token" });
const tokens = await sdk.oauth().exchangeCode(code, state);

PKCE (Phase 2)

PKCE (Proof Key for Code Exchange) is required for public clients (SPAs, native apps) and recommended for all flows.

let (auth_url, verifier) = engine.oauth().authorization_url()
    .pkce()
    .state("random-csrf-token")
    .build_with_verifier();

// Store verifier in session, use it at callback
let tokens = engine.oauth()
    .exchange_code_pkce(code, state, verifier)
    .await?;
auth_url, verifier = _sdk.oauth().authorization_url_pkce(state="random-csrf-token")

# Store verifier in session, use it at callback
tokens = await _sdk.oauth().exchange_code_pkce(
    code=code, state=state, verifier=verifier
)
// Phase 2 — Go SDK ships in Phase 2.
authURL, verifier := s.OAuth().AuthorizationURLPKCE(sdk.AuthURLOptions{State: "random-csrf-token"})
tokens, err := s.OAuth().ExchangeCodePKCE(ctx, code, state, verifier)
// Phase 2 — TypeScript SDK ships in Phase 2.
const { url: authUrl, verifier } = sdk.oauth().authorizationUrlPkce({ state: "random-csrf-token" });
const tokens = await sdk.oauth().exchangeCodePkce(code, state, verifier);

OIDC discovery (Phase 2)

Point CoreSDK at an OIDC discovery document to configure all endpoints automatically.

// Set CORESDK_JWKS_URL to the issuer discovery URL.
// Engine::from_env() fetches /.well-known/openid-configuration automatically.
let engine = Engine::from_env()?;
import os
os.environ["CORESDK_JWKS_URL"] = "https://accounts.google.com/.well-known/openid-configuration"

_sdk = CoreSDKClient(SDKConfig.from_env())
// Phase 2 — Go SDK ships in Phase 2.
s := sdk.New(sdk.Config{
    SidecarAddr:     "http://127.0.0.1:7233",
    TenantID:        "acme",
    OIDCIssuer:      "https://accounts.google.com",
    OAuthClientID:   "client_abc123",
    OAuthClientSecret: "secret_xyz",
})
// Phase 2 — TypeScript SDK ships in Phase 2.
const sdk = new CoreSDKClient({
  sidecarAddr: "http://127.0.0.1:7233",
  tenantId: "acme",
  oidcIssuer: "https://accounts.google.com",
  oauth: { clientId: "client_abc123", clientSecret: "secret_xyz" },
});

Environment variables

VariableDescription
CORESDK_JWKS_URLJWKS endpoint or OIDC discovery URL
CORESDK_SIDECAR_ADDRSidecar address (default: http://127.0.0.1:7233)
CORESDK_TENANT_IDTenant identifier

Next steps

On this page