fix: validate and respect oidc validation settings
This commit is contained in:
parent
c9bcc1d7c6
commit
e713dae91b
@ -10,6 +10,7 @@ import { parse } from 'yaml'
|
||||
|
||||
import { IntegrationFactory, loadIntegration } from '~/integration'
|
||||
import { HeadscaleConfig, loadConfig } from '~/utils/config/headscale'
|
||||
import { testOidc } from '~/utils/oidc'
|
||||
import log from '~/utils/log'
|
||||
|
||||
export interface HeadplaneContext {
|
||||
@ -157,6 +158,7 @@ async function checkOidc(config?: HeadscaleConfig) {
|
||||
let client = process.env.OIDC_CLIENT_ID
|
||||
let secret = process.env.OIDC_CLIENT_SECRET
|
||||
let method = process.env.OIDC_CLIENT_SECRET_METHOD ?? 'client_secret_basic'
|
||||
let skip = process.env.OIDC_SKIP_CONFIG_VALIDATION === 'true'
|
||||
|
||||
log.debug('CTXT', 'Checking OIDC environment variables')
|
||||
log.debug('CTXT', 'Issuer: %s', issuer)
|
||||
@ -171,6 +173,14 @@ async function checkOidc(config?: HeadscaleConfig) {
|
||||
}
|
||||
|
||||
if (issuer && client && secret) {
|
||||
if (!skip) {
|
||||
log.debug('CTXT', 'Validating OIDC configuration from environment variables')
|
||||
testOidc(issuer, client, secret)
|
||||
} else {
|
||||
log.debug('CTXT', 'OIDC_SKIP_CONFIG_VALIDATION is set')
|
||||
log.debug('CTXT', 'Skipping OIDC configuration validation')
|
||||
}
|
||||
|
||||
return {
|
||||
issuer,
|
||||
client,
|
||||
@ -214,6 +224,15 @@ async function checkOidc(config?: HeadscaleConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
if (config.oidc.only_start_if_oidc_is_available) {
|
||||
log.debug('CTXT', 'Validating OIDC configuration from headscale config')
|
||||
testOidc(issuer, client, secret)
|
||||
return
|
||||
} else {
|
||||
log.debug('CTXT', 'OIDC validation is disabled in headscale config')
|
||||
log.debug('CTXT', 'Skipping OIDC configuration validation')
|
||||
}
|
||||
|
||||
return {
|
||||
issuer,
|
||||
client,
|
||||
|
||||
@ -17,6 +17,7 @@ import {
|
||||
|
||||
import { post } from '~/utils/headscale'
|
||||
import { commitSession, getSession } from '~/utils/sessions'
|
||||
import log from '~/utils/log'
|
||||
|
||||
import { HeadplaneContext } from './config/headplane'
|
||||
|
||||
@ -169,3 +170,30 @@ export async function finishOidc(oidc: OidcConfig, req: Request) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Runs at application startup to validate the OIDC configuration
|
||||
export async function testOidc(issuer: string, client: string, secret: string) {
|
||||
const oidcClient = {
|
||||
client_id: client,
|
||||
client_secret: secret,
|
||||
token_endpoint_auth_method: 'client_secret_post',
|
||||
} satisfies Client
|
||||
|
||||
const issuerUrl = new URL(issuer)
|
||||
|
||||
try {
|
||||
log.debug('OIDC', 'Checking OIDC well-known endpoint')
|
||||
const response = await discoveryRequest(issuerUrl)
|
||||
const processed = await processDiscoveryResponse(issuerUrl, response)
|
||||
if (!processed.authorization_endpoint) {
|
||||
log.debug('OIDC', 'No authorization endpoint found on the OIDC provider')
|
||||
return false
|
||||
}
|
||||
|
||||
log.debug('OIDC', 'Found auth endpoint: %s', processed.authorization_endpoint)
|
||||
return true
|
||||
} catch (e) {
|
||||
log.debug('OIDC', 'Validation failed: %s', e.message)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ If you use the Headscale configuration integration, these are not required.
|
||||
- **`OIDC_CLIENT_ID`**: The client ID of your OIDC provider.
|
||||
- **`OIDC_CLIENT_SECRET`**: The client secret of your OIDC provider.
|
||||
- **`OIDC_CLIENT_SECRET_METHOD`**: The method used to send the client secret (default: `client_secret_basic`).
|
||||
- **`OIDC_SKIP_CONFIG_VALIDATION`**: Skip the OIDC configuration validation (default: `false`).
|
||||
- **`ROOT_API_KEY`**: An API key used to issue new ones for sessions (keep expiry fairly long).
|
||||
- **`DISABLE_API_KEY_LOGIN`**: If you want to disable API key login, set this to `true`.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user