Skip to main content

createNAuthOIDCProvider

Package: @nauth-toolkit/oidc-provider Type: Factory

Builds an oidc-provider instance backed by nauth-toolkit's storage and users, with the defaults listed below already applied.

import { createNAuthOIDCProvider } from '@nauth-toolkit/oidc-provider';
async function createNAuthOIDCProvider(options: NAuthOIDCOptions): Promise<Provider>

With NestJS you do not call this directly — OIDCProviderModule.forRoot() does, supplying storage and userRepository from AuthModule.

Options​

NAuthOIDCOptions:

PropertyTypeRequiredDescription
clientsNAuthOIDCClient[]NoStatically registered clients. Default []
cookieKeysstring[]YesKeygrip signing keys for the provider's own cookies. Separate from nauth-toolkit's JWT secrets. Rotate by prepending a new key
extraConfigurationPartial<Configuration>NoEscape hatch for any oidc-provider option this wrapper does not surface. Merged last, so it overrides everything
interactionUrl(uid: string) => stringYesWhere the browser is sent when the provider needs the user to do something
issuerstringYesThe public origin, with no path component. See the warning below
jwks{ keys: Record<string, unknown>[] }NoKeys used to sign id_tokens. A development key is generated when omitted
pathPrefixstringNoPath every provider endpoint is served under. Default '/oidc'
proxybooleanNoTrust X-Forwarded-*. Required behind a reverse proxy. Default false
secureCookiesbooleanNoMark cookies secure. Set false for plain-http local development. Default true
storageStorageAdapterYesnauth-toolkit's storage adapter. Backs every provider model; no tables are created
userRepositoryRepository<BaseUser>YesUsed to resolve accounts and release claims
issuer must be an origin

oidc-provider builds every endpoint URL as new URL(absolutePath, issuer), so any path on the issuer is silently discarded — new URL('/auth', 'https://host/oidc') is https://host/auth, and the discovery document then advertises endpoints that 404. Namespace with pathPrefix instead.

Set jwks outside local development

Omitting it generates a fresh development key on every start, which invalidates every id_token already issued. Generate a persistent key set and pass it in.

Client metadata​

NAuthOIDCClient:

PropertyTypeRequiredDescription
client_idstringYesPublic identifier, sent as client_id
client_namestringNoHuman-readable name, shown on the consent screen
client_secretstringNoOmit for a public client, which must then use PKCE
client_uristringNoClient home page, shown on the consent screen. Absolute http(s) URL
grant_typesstring[]NoDefault ['authorization_code', 'refresh_token']
logo_uristringNoLogo shown on the consent screen. Absolute http(s) URL
post_logout_redirect_urisstring[]NoAllowed targets for RP-initiated logout
redirect_urisstring[]YesMatched as exact strings
response_types'code'[]NoDefault ['code']; nothing else is available
token_endpoint_auth_method'client_secret_basic' | 'client_secret_post' | 'none'NoDefault 'client_secret_basic'

Any other metadata oidc-provider accepts may be set alongside these.

Defaults applied​

oidc-provider defaultApplied here
responseTypescode, id_token, code id_token, none['code']
pkce.requiredPublic clients onlyEvery client
features.introspectionDisabledEnabled, scoped to a client's own tokens
features.revocationDisabledEnabled, scoped to a client's own tokens
features.devInteractionsEnabledDisabled
issueRefreshTokenRequires offline_accessRequires only the registered grant
ttlWarn-on-defaultSet explicitly — see below

Released scopes are openid and offline_access, plus the email, profile and phone claim scopes.

Lifetimes​

ArtifactTTL
AccessToken3600 s
AuthorizationCode60 s
Grant14 days
IdToken3600 s
Interaction900 s
RefreshToken30 days
Session14 days

extraConfiguration​

Merged after everything above, so it wins. Use it to override lifetimes, replace the RP-initiated logout screens, or reach any oidc-provider option:

extraConfiguration: {
ttl: { AccessToken: 15 * 60 },
},

Example​

src/oidc.ts
import { createNAuthOIDCProvider } from '@nauth-toolkit/oidc-provider';

const provider = await createNAuthOIDCProvider({
issuer: 'https://auth.example.com',
pathPrefix: '/oidc',
interactionUrl: (uid) => `https://auth.example.com/interaction/${uid}`,
storage: nauth.storage,
userRepository,
cookieKeys: [process.env.OIDC_COOKIE_SECRET!],
proxy: true,
clients: [
{
client_id: 'partner',
client_secret: process.env.PARTNER_CLIENT_SECRET!,
client_name: 'Partner App',
redirect_uris: ['https://myapp.com/callback'],
},
],
});

What's Next​