mirror of
https://github.com/element-hq/matrix-authentication-service.git
synced 2026-07-28 20:49:23 +00:00
2964 lines
91 KiB
JSON
2964 lines
91 KiB
JSON
{
|
||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||
"title": "RootConfig",
|
||
"description": "Application configuration root",
|
||
"type": "object",
|
||
"properties": {
|
||
"clients": {
|
||
"description": "List of OAuth 2.0/OIDC clients config",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ClientsConfig"
|
||
}
|
||
]
|
||
},
|
||
"http": {
|
||
"description": "Configuration of the HTTP server",
|
||
"default": {
|
||
"listeners": [
|
||
{
|
||
"name": "web",
|
||
"resources": [
|
||
{
|
||
"name": "discovery"
|
||
},
|
||
{
|
||
"name": "human"
|
||
},
|
||
{
|
||
"name": "oauth"
|
||
},
|
||
{
|
||
"name": "compat"
|
||
},
|
||
{
|
||
"name": "graphql"
|
||
},
|
||
{
|
||
"name": "assets"
|
||
}
|
||
],
|
||
"binds": [
|
||
{
|
||
"address": "[::]:8080"
|
||
}
|
||
],
|
||
"proxy_protocol": false
|
||
},
|
||
{
|
||
"name": "internal",
|
||
"resources": [
|
||
{
|
||
"name": "health"
|
||
}
|
||
],
|
||
"binds": [
|
||
{
|
||
"host": "localhost",
|
||
"port": 8081
|
||
}
|
||
],
|
||
"proxy_protocol": false
|
||
}
|
||
],
|
||
"trusted_proxies": [
|
||
"192.168.0.0/16",
|
||
"172.16.0.0/12",
|
||
"10.0.0.0/10",
|
||
"127.0.0.1/8",
|
||
"fd00::/8",
|
||
"::1/128"
|
||
],
|
||
"public_base": "http://[::]:8080/",
|
||
"issuer": "http://[::]:8080/"
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/HttpConfig"
|
||
}
|
||
]
|
||
},
|
||
"database": {
|
||
"description": "Database connection configuration",
|
||
"default": {
|
||
"uri": "postgresql://",
|
||
"max_connections": 10,
|
||
"min_connections": 0,
|
||
"connect_timeout": 30,
|
||
"idle_timeout": 600,
|
||
"max_lifetime": 1800
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/DatabaseConfig"
|
||
}
|
||
]
|
||
},
|
||
"telemetry": {
|
||
"description": "Configuration related to sending monitoring data",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/TelemetryConfig"
|
||
}
|
||
]
|
||
},
|
||
"templates": {
|
||
"description": "Configuration related to templates",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/TemplatesConfig"
|
||
}
|
||
]
|
||
},
|
||
"email": {
|
||
"description": "Configuration related to sending emails",
|
||
"default": {
|
||
"from": "\"Authentication Service\" <root@localhost>",
|
||
"reply_to": "\"Authentication Service\" <root@localhost>",
|
||
"transport": "blackhole"
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/EmailConfig"
|
||
}
|
||
]
|
||
},
|
||
"secrets": {
|
||
"description": "Application secrets",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/SecretsConfig"
|
||
}
|
||
]
|
||
},
|
||
"passwords": {
|
||
"description": "Configuration related to user passwords",
|
||
"default": {
|
||
"enabled": true,
|
||
"schemes": [
|
||
{
|
||
"version": 1,
|
||
"algorithm": "argon2id"
|
||
}
|
||
],
|
||
"minimum_complexity": 3
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/PasswordsConfig"
|
||
}
|
||
]
|
||
},
|
||
"matrix": {
|
||
"description": "Configuration related to the homeserver",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/MatrixConfig"
|
||
}
|
||
]
|
||
},
|
||
"policy": {
|
||
"description": "Configuration related to the OPA policies",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/PolicyConfig"
|
||
}
|
||
]
|
||
},
|
||
"rate_limiting": {
|
||
"description": "Configuration related to limiting the rate of user actions to prevent\nabuse",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimitingConfig"
|
||
}
|
||
]
|
||
},
|
||
"upstream_oauth2": {
|
||
"description": "Configuration related to upstream OAuth providers",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/UpstreamOAuth2Config"
|
||
}
|
||
]
|
||
},
|
||
"branding": {
|
||
"description": "Configuration section for tweaking the branding of the service",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/BrandingConfig"
|
||
}
|
||
]
|
||
},
|
||
"captcha": {
|
||
"description": "Configuration section to setup CAPTCHA protection on a few operations",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/CaptchaConfig"
|
||
}
|
||
]
|
||
},
|
||
"account": {
|
||
"description": "Configuration section to configure features related to account\nmanagement",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/AccountConfig"
|
||
}
|
||
]
|
||
},
|
||
"oauth": {
|
||
"description": "Configuration section for OAuth 2.0 protocol options",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/OAuthConfig"
|
||
}
|
||
]
|
||
},
|
||
"experimental": {
|
||
"description": "Experimental configuration options",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ExperimentalConfig"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"secrets",
|
||
"matrix"
|
||
],
|
||
"definitions": {
|
||
"ClientsConfig": {
|
||
"description": "List of OAuth 2.0/OIDC clients config",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/ClientConfig"
|
||
}
|
||
},
|
||
"ClientConfig": {
|
||
"description": "An OAuth 2.0 client configuration",
|
||
"type": "object",
|
||
"properties": {
|
||
"client_id": {
|
||
"description": "A ULID as per https://github.com/ulid/spec",
|
||
"type": "string",
|
||
"pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
|
||
},
|
||
"client_auth_method": {
|
||
"description": "Authentication method used for this client",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ClientAuthMethodConfig"
|
||
}
|
||
]
|
||
},
|
||
"client_name": {
|
||
"description": "Name of the `OAuth2` client",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"client_secret_file": {
|
||
"description": "Path to the file containing the client secret. The client secret is used\nby the `client_secret_basic`, `client_secret_post` and\n`client_secret_jwt` authentication methods.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"client_secret": {
|
||
"description": "Alternative to `client_secret_file`: Reads the client secret directly\nfrom the config.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"jwks": {
|
||
"description": "The JSON Web Key Set (JWKS) used by the `private_key_jwt` authentication\nmethod. Mutually exclusive with `jwks_uri`",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/JsonWebKeySet"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"jwks_uri": {
|
||
"description": "The URL of the JSON Web Key Set (JWKS) used by the `private_key_jwt`\nauthentication method. Mutually exclusive with `jwks`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"redirect_uris": {
|
||
"description": "List of allowed redirect URIs",
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string",
|
||
"format": "uri"
|
||
}
|
||
}
|
||
},
|
||
"required": [
|
||
"client_id",
|
||
"client_auth_method"
|
||
]
|
||
},
|
||
"ClientAuthMethodConfig": {
|
||
"description": "Authentication method used by clients",
|
||
"oneOf": [
|
||
{
|
||
"description": "`none`: No authentication",
|
||
"type": "string",
|
||
"const": "none"
|
||
},
|
||
{
|
||
"description": "`client_secret_basic`: `client_id` and `client_secret` used as basic\nauthorization credentials",
|
||
"type": "string",
|
||
"const": "client_secret_basic"
|
||
},
|
||
{
|
||
"description": "`client_secret_post`: `client_id` and `client_secret` sent in the\nrequest body",
|
||
"type": "string",
|
||
"const": "client_secret_post"
|
||
},
|
||
{
|
||
"description": "`client_secret_basic`: a `client_assertion` sent in the request body and\nsigned using the `client_secret`",
|
||
"type": "string",
|
||
"const": "client_secret_jwt"
|
||
},
|
||
{
|
||
"description": "`client_secret_basic`: a `client_assertion` sent in the request body and\nsigned by an asymmetric key",
|
||
"type": "string",
|
||
"const": "private_key_jwt"
|
||
}
|
||
]
|
||
},
|
||
"JsonWebKeySet": {
|
||
"type": "object",
|
||
"properties": {
|
||
"keys": {
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/JsonWebKey"
|
||
}
|
||
}
|
||
},
|
||
"required": [
|
||
"keys"
|
||
]
|
||
},
|
||
"JsonWebKey": {
|
||
"type": "object",
|
||
"properties": {
|
||
"use": {
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/JsonWebKeyUse"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"key_ops": {
|
||
"type": [
|
||
"array",
|
||
"null"
|
||
],
|
||
"items": {
|
||
"$ref": "#/definitions/JsonWebKeyOperation"
|
||
}
|
||
},
|
||
"alg": {
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/JsonWebSignatureAlg"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"kid": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"x5u": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"x5c": {
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"x5t": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"x5t#S256": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
},
|
||
"oneOf": [
|
||
{
|
||
"type": "object",
|
||
"properties": {
|
||
"kty": {
|
||
"type": "string",
|
||
"const": "RSA"
|
||
}
|
||
},
|
||
"required": [
|
||
"kty"
|
||
],
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RsaPublicParameters"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"type": "object",
|
||
"properties": {
|
||
"kty": {
|
||
"type": "string",
|
||
"const": "EC"
|
||
}
|
||
},
|
||
"required": [
|
||
"kty"
|
||
],
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/EcPublicParameters"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"type": "object",
|
||
"properties": {
|
||
"kty": {
|
||
"type": "string",
|
||
"const": "OKP"
|
||
}
|
||
},
|
||
"required": [
|
||
"kty"
|
||
],
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/OkpPublicParameters"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"RsaPublicParameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"n": {
|
||
"type": "string"
|
||
},
|
||
"e": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"n",
|
||
"e"
|
||
]
|
||
},
|
||
"JsonWebKeyEcEllipticCurve": {
|
||
"description": "JSON Web Key EC Elliptic Curve",
|
||
"anyOf": [
|
||
{
|
||
"description": "P-256 Curve",
|
||
"const": "P-256"
|
||
},
|
||
{
|
||
"description": "P-384 Curve",
|
||
"const": "P-384"
|
||
},
|
||
{
|
||
"description": "P-521 Curve",
|
||
"const": "P-521"
|
||
},
|
||
{
|
||
"description": "SECG secp256k1 curve",
|
||
"const": "secp256k1"
|
||
}
|
||
]
|
||
},
|
||
"EcPublicParameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"crv": {
|
||
"$ref": "#/definitions/JsonWebKeyEcEllipticCurve"
|
||
},
|
||
"x": {
|
||
"type": "string"
|
||
},
|
||
"y": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"crv",
|
||
"x",
|
||
"y"
|
||
]
|
||
},
|
||
"JsonWebKeyOkpEllipticCurve": {
|
||
"description": "JSON Web Key OKP Elliptic Curve",
|
||
"anyOf": [
|
||
{
|
||
"description": "Ed25519 signature algorithm key pairs",
|
||
"const": "Ed25519"
|
||
},
|
||
{
|
||
"description": "Ed448 signature algorithm key pairs",
|
||
"const": "Ed448"
|
||
},
|
||
{
|
||
"description": "X25519 function key pairs",
|
||
"const": "X25519"
|
||
},
|
||
{
|
||
"description": "X448 function key pairs",
|
||
"const": "X448"
|
||
}
|
||
]
|
||
},
|
||
"OkpPublicParameters": {
|
||
"type": "object",
|
||
"properties": {
|
||
"crv": {
|
||
"$ref": "#/definitions/JsonWebKeyOkpEllipticCurve"
|
||
},
|
||
"x": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"crv",
|
||
"x"
|
||
]
|
||
},
|
||
"JsonWebKeyUse": {
|
||
"description": "JSON Web Key Use",
|
||
"anyOf": [
|
||
{
|
||
"description": "Digital Signature or MAC",
|
||
"const": "sig"
|
||
},
|
||
{
|
||
"description": "Encryption",
|
||
"const": "enc"
|
||
}
|
||
]
|
||
},
|
||
"JsonWebKeyOperation": {
|
||
"description": "JSON Web Key Operation",
|
||
"anyOf": [
|
||
{
|
||
"description": "Compute digital signature or MAC",
|
||
"const": "sign"
|
||
},
|
||
{
|
||
"description": "Verify digital signature or MAC",
|
||
"const": "verify"
|
||
},
|
||
{
|
||
"description": "Encrypt content",
|
||
"const": "encrypt"
|
||
},
|
||
{
|
||
"description": "Decrypt content and validate decryption, if applicable",
|
||
"const": "decrypt"
|
||
},
|
||
{
|
||
"description": "Encrypt key",
|
||
"const": "wrapKey"
|
||
},
|
||
{
|
||
"description": "Decrypt key and validate decryption, if applicable",
|
||
"const": "unwrapKey"
|
||
},
|
||
{
|
||
"description": "Derive key",
|
||
"const": "deriveKey"
|
||
},
|
||
{
|
||
"description": "Derive bits not to be used as a key",
|
||
"const": "deriveBits"
|
||
}
|
||
]
|
||
},
|
||
"JsonWebSignatureAlg": {
|
||
"description": "JSON Web Signature \"alg\" parameter",
|
||
"anyOf": [
|
||
{
|
||
"description": "HMAC using SHA-256",
|
||
"const": "HS256"
|
||
},
|
||
{
|
||
"description": "HMAC using SHA-384",
|
||
"const": "HS384"
|
||
},
|
||
{
|
||
"description": "HMAC using SHA-512",
|
||
"const": "HS512"
|
||
},
|
||
{
|
||
"description": "RSASSA-PKCS1-v1_5 using SHA-256",
|
||
"const": "RS256"
|
||
},
|
||
{
|
||
"description": "RSASSA-PKCS1-v1_5 using SHA-384",
|
||
"const": "RS384"
|
||
},
|
||
{
|
||
"description": "RSASSA-PKCS1-v1_5 using SHA-512",
|
||
"const": "RS512"
|
||
},
|
||
{
|
||
"description": "ECDSA using P-256 and SHA-256",
|
||
"const": "ES256"
|
||
},
|
||
{
|
||
"description": "ECDSA using P-384 and SHA-384",
|
||
"const": "ES384"
|
||
},
|
||
{
|
||
"description": "ECDSA using P-521 and SHA-512",
|
||
"const": "ES512"
|
||
},
|
||
{
|
||
"description": "RSASSA-PSS using SHA-256 and MGF1 with SHA-256",
|
||
"const": "PS256"
|
||
},
|
||
{
|
||
"description": "RSASSA-PSS using SHA-384 and MGF1 with SHA-384",
|
||
"const": "PS384"
|
||
},
|
||
{
|
||
"description": "RSASSA-PSS using SHA-512 and MGF1 with SHA-512",
|
||
"const": "PS512"
|
||
},
|
||
{
|
||
"description": "No digital signature or MAC performed",
|
||
"const": "none"
|
||
},
|
||
{
|
||
"description": "EdDSA signature algorithms",
|
||
"const": "EdDSA"
|
||
},
|
||
{
|
||
"description": "ECDSA using secp256k1 curve and SHA-256",
|
||
"const": "ES256K"
|
||
},
|
||
{
|
||
"description": "EdDSA using Ed25519 curve",
|
||
"const": "Ed25519"
|
||
},
|
||
{
|
||
"description": "EdDSA using Ed448 curve",
|
||
"const": "Ed448"
|
||
}
|
||
]
|
||
},
|
||
"HttpConfig": {
|
||
"description": "Configuration related to the web server",
|
||
"type": "object",
|
||
"properties": {
|
||
"listeners": {
|
||
"description": "List of listeners to run",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/ListenerConfig"
|
||
},
|
||
"default": []
|
||
},
|
||
"trusted_proxies": {
|
||
"description": "List of trusted reverse proxies that can set the `X-Forwarded-For`\nheader",
|
||
"type": "array",
|
||
"items": {
|
||
"type": "string",
|
||
"format": "ip"
|
||
},
|
||
"default": [
|
||
"192.168.0.0/16",
|
||
"172.16.0.0/12",
|
||
"10.0.0.0/10",
|
||
"127.0.0.1/8",
|
||
"fd00::/8",
|
||
"::1/128"
|
||
]
|
||
},
|
||
"public_base": {
|
||
"description": "Public URL base from where the authentication service is reachable",
|
||
"type": "string",
|
||
"format": "uri"
|
||
},
|
||
"issuer": {
|
||
"description": "OIDC issuer URL. Defaults to `public_base` if not set.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
}
|
||
},
|
||
"required": [
|
||
"public_base"
|
||
]
|
||
},
|
||
"ListenerConfig": {
|
||
"description": "Configuration of a listener",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"description": "A unique name for this listener which will be shown in traces and in\nmetrics labels",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"resources": {
|
||
"description": "List of resources to mount",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/Resource"
|
||
}
|
||
},
|
||
"prefix": {
|
||
"description": "HTTP prefix to mount the resources on",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"binds": {
|
||
"description": "List of sockets to bind",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/BindConfig"
|
||
}
|
||
},
|
||
"proxy_protocol": {
|
||
"description": "Accept `HAProxy`'s Proxy Protocol V1",
|
||
"type": "boolean",
|
||
"default": false
|
||
},
|
||
"tls": {
|
||
"description": "If set, makes the listener use TLS with the provided certificate and key",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/TlsConfig"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"resources",
|
||
"binds"
|
||
]
|
||
},
|
||
"Resource": {
|
||
"description": "HTTP resources to mount",
|
||
"oneOf": [
|
||
{
|
||
"description": "Healthcheck endpoint (/health)",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "health"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "Prometheus metrics endpoint (/metrics)",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "prometheus"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "OIDC discovery endpoints",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "discovery"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "Pages destined to be viewed by humans",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "human"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "GraphQL endpoint",
|
||
"type": "object",
|
||
"properties": {
|
||
"playground": {
|
||
"description": "Enabled the GraphQL playground",
|
||
"type": "boolean"
|
||
},
|
||
"undocumented_oauth2_access": {
|
||
"description": "Allow access for OAuth 2.0 clients (undocumented)",
|
||
"type": "boolean"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"const": "graphql"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "OAuth-related APIs",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "oauth"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "Matrix compatibility API",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "compat"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "Static files",
|
||
"type": "object",
|
||
"properties": {
|
||
"path": {
|
||
"description": "Path to the directory to serve.",
|
||
"type": "string"
|
||
},
|
||
"name": {
|
||
"type": "string",
|
||
"const": "assets"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "Admin API, served at `/api/admin/v1`",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "adminapi"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
},
|
||
{
|
||
"description": "Mount a \"/connection-info\" handler which helps debugging informations on\nthe upstream connection",
|
||
"type": "object",
|
||
"properties": {
|
||
"name": {
|
||
"type": "string",
|
||
"const": "connection-info"
|
||
}
|
||
},
|
||
"required": [
|
||
"name"
|
||
]
|
||
}
|
||
]
|
||
},
|
||
"BindConfig": {
|
||
"description": "Configuration of a single listener",
|
||
"anyOf": [
|
||
{
|
||
"description": "Listen on the specified host and port",
|
||
"type": "object",
|
||
"properties": {
|
||
"host": {
|
||
"description": "Host on which to listen.\n\nDefaults to listening on all addresses",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"port": {
|
||
"description": "Port on which to listen.",
|
||
"type": "integer",
|
||
"format": "uint16",
|
||
"minimum": 0,
|
||
"maximum": 65535
|
||
}
|
||
},
|
||
"required": [
|
||
"port"
|
||
]
|
||
},
|
||
{
|
||
"description": "Listen on the specified address",
|
||
"type": "object",
|
||
"properties": {
|
||
"address": {
|
||
"description": "Host and port on which to listen",
|
||
"type": "string",
|
||
"examples": [
|
||
"[::1]:8080",
|
||
"[::]:8080",
|
||
"127.0.0.1:8080",
|
||
"0.0.0.0:8080"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"address"
|
||
]
|
||
},
|
||
{
|
||
"description": "Listen on a UNIX domain socket",
|
||
"type": "object",
|
||
"properties": {
|
||
"socket": {
|
||
"description": "Path to the socket",
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"socket"
|
||
]
|
||
},
|
||
{
|
||
"description": "Accept connections on file descriptors passed by the parent process.\n\nThis is useful for grabbing sockets passed by systemd.\n\nSee <https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html>",
|
||
"type": "object",
|
||
"properties": {
|
||
"fd": {
|
||
"description": "Index of the file descriptor. Note that this is offseted by 3\nbecause of the standard input/output sockets, so setting\nhere a value of `0` will grab the file descriptor `3`",
|
||
"type": "integer",
|
||
"format": "uint",
|
||
"minimum": 0,
|
||
"default": 0
|
||
},
|
||
"kind": {
|
||
"description": "Whether the socket is a TCP socket or a UNIX domain socket. Defaults\nto TCP.",
|
||
"default": "tcp",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/UnixOrTcp"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
}
|
||
]
|
||
},
|
||
"UnixOrTcp": {
|
||
"description": "Kind of socket",
|
||
"oneOf": [
|
||
{
|
||
"description": "UNIX domain socket",
|
||
"type": "string",
|
||
"const": "unix"
|
||
},
|
||
{
|
||
"description": "TCP socket",
|
||
"type": "string",
|
||
"const": "tcp"
|
||
}
|
||
]
|
||
},
|
||
"TlsConfig": {
|
||
"description": "Configuration related to TLS on a listener",
|
||
"type": "object",
|
||
"properties": {
|
||
"certificate": {
|
||
"description": "PEM-encoded X509 certificate chain\n\nExactly one of `certificate` or `certificate_file` must be set.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"certificate_file": {
|
||
"description": "File containing the PEM-encoded X509 certificate chain\n\nExactly one of `certificate` or `certificate_file` must be set.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"key": {
|
||
"description": "PEM-encoded private key\n\nExactly one of `key` or `key_file` must be set.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"key_file": {
|
||
"description": "File containing a PEM or DER-encoded private key\n\nExactly one of `key` or `key_file` must be set.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"password": {
|
||
"description": "Password used to decode the private key\n\nOne of `password` or `password_file` must be set if the key is\nencrypted.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"password_file": {
|
||
"description": "Password file used to decode the private key\n\nOne of `password` or `password_file` must be set if the key is\nencrypted.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"DatabaseConfig": {
|
||
"description": "Database connection configuration",
|
||
"type": "object",
|
||
"properties": {
|
||
"uri": {
|
||
"description": "Connection URI\n\nThis must not be specified if `host`, `port`, `socket`, `username`,\n`password`, or `database` are specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri",
|
||
"default": "postgresql://"
|
||
},
|
||
"host": {
|
||
"description": "Name of host to connect to\n\nThis must not be specified if `uri` is specified.",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/Hostname"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"port": {
|
||
"description": "Port number to connect at the server host\n\nThis must not be specified if `uri` is specified.",
|
||
"type": [
|
||
"integer",
|
||
"null"
|
||
],
|
||
"format": "uint16",
|
||
"minimum": 1,
|
||
"maximum": 65535
|
||
},
|
||
"socket": {
|
||
"description": "Directory containing the UNIX socket to connect to\n\nThis must not be specified if `uri` is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"username": {
|
||
"description": "PostgreSQL user name to connect as\n\nThis must not be specified if `uri` is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"password": {
|
||
"description": "Password to be used if the server demands password authentication\n\nThis must not be specified if `uri` is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"database": {
|
||
"description": "The database name\n\nThis must not be specified if `uri` is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"ssl_mode": {
|
||
"description": "How to handle SSL connections",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/PgSslMode"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"ssl_ca": {
|
||
"description": "The PEM-encoded root certificate for SSL connections\n\nThis must not be specified if the `ssl_ca_file` option is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"ssl_ca_file": {
|
||
"description": "Path to the root certificate for SSL connections\n\nThis must not be specified if the `ssl_ca` option is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"ssl_certificate": {
|
||
"description": "The PEM-encoded client certificate for SSL connections\n\nThis must not be specified if the `ssl_certificate_file` option is\nspecified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"ssl_certificate_file": {
|
||
"description": "Path to the client certificate for SSL connections\n\nThis must not be specified if the `ssl_certificate` option is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"ssl_key": {
|
||
"description": "The PEM-encoded client key for SSL connections\n\nThis must not be specified if the `ssl_key_file` option is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"ssl_key_file": {
|
||
"description": "Path to the client key for SSL connections\n\nThis must not be specified if the `ssl_key` option is specified.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"max_connections": {
|
||
"description": "Set the maximum number of connections the pool should maintain",
|
||
"type": "integer",
|
||
"format": "uint32",
|
||
"minimum": 1,
|
||
"default": 10
|
||
},
|
||
"min_connections": {
|
||
"description": "Set the minimum number of connections the pool should maintain",
|
||
"type": "integer",
|
||
"format": "uint32",
|
||
"minimum": 0,
|
||
"default": 0
|
||
},
|
||
"connect_timeout": {
|
||
"description": "Set the amount of time to attempt connecting to the database",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 0,
|
||
"default": 30
|
||
},
|
||
"idle_timeout": {
|
||
"description": "Set a maximum idle duration for individual connections",
|
||
"type": [
|
||
"integer",
|
||
"null"
|
||
],
|
||
"format": "uint64",
|
||
"minimum": 0,
|
||
"default": 600
|
||
},
|
||
"max_lifetime": {
|
||
"description": "Set the maximum lifetime of individual connections",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 0,
|
||
"default": 1800
|
||
}
|
||
}
|
||
},
|
||
"Hostname": {
|
||
"type": "string",
|
||
"format": "hostname"
|
||
},
|
||
"PgSslMode": {
|
||
"description": "Options for controlling the level of protection provided for PostgreSQL SSL\nconnections.",
|
||
"oneOf": [
|
||
{
|
||
"description": "Only try a non-SSL connection.",
|
||
"type": "string",
|
||
"const": "disable"
|
||
},
|
||
{
|
||
"description": "First try a non-SSL connection; if that fails, try an SSL connection.",
|
||
"type": "string",
|
||
"const": "allow"
|
||
},
|
||
{
|
||
"description": "First try an SSL connection; if that fails, try a non-SSL connection.",
|
||
"type": "string",
|
||
"const": "prefer"
|
||
},
|
||
{
|
||
"description": "Only try an SSL connection. If a root CA file is present, verify the\nconnection in the same way as if `VerifyCa` was specified.",
|
||
"type": "string",
|
||
"const": "require"
|
||
},
|
||
{
|
||
"description": "Only try an SSL connection, and verify that the server certificate is\nissued by a trusted certificate authority (CA).",
|
||
"type": "string",
|
||
"const": "verify-ca"
|
||
},
|
||
{
|
||
"description": "Only try an SSL connection; verify that the server certificate is issued\nby a trusted CA and that the requested server host name matches that\nin the certificate.",
|
||
"type": "string",
|
||
"const": "verify-full"
|
||
}
|
||
]
|
||
},
|
||
"TelemetryConfig": {
|
||
"description": "Configuration related to sending monitoring data",
|
||
"type": "object",
|
||
"properties": {
|
||
"tracing": {
|
||
"description": "Configuration related to exporting traces",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/TracingConfig"
|
||
}
|
||
]
|
||
},
|
||
"metrics": {
|
||
"description": "Configuration related to exporting metrics",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/MetricsConfig"
|
||
}
|
||
]
|
||
},
|
||
"sentry": {
|
||
"description": "Configuration related to the Sentry integration",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/SentryConfig"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"TracingConfig": {
|
||
"description": "Configuration related to exporting traces",
|
||
"type": "object",
|
||
"properties": {
|
||
"exporter": {
|
||
"description": "Exporter to use when exporting traces",
|
||
"default": "none",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/TracingExporterKind"
|
||
}
|
||
]
|
||
},
|
||
"endpoint": {
|
||
"description": "OTLP exporter: OTLP over HTTP compatible endpoint",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri",
|
||
"default": "https://localhost:4318"
|
||
},
|
||
"propagators": {
|
||
"description": "List of propagation formats to use for incoming and outgoing requests",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/Propagator"
|
||
},
|
||
"default": []
|
||
},
|
||
"sample_rate": {
|
||
"description": "Sample rate for traces\n\nDefaults to `1.0` if not set.",
|
||
"type": [
|
||
"number",
|
||
"null"
|
||
],
|
||
"format": "double",
|
||
"examples": [
|
||
0.5
|
||
],
|
||
"minimum": 0.0,
|
||
"maximum": 1.0
|
||
}
|
||
}
|
||
},
|
||
"TracingExporterKind": {
|
||
"description": "Exporter to use when exporting traces",
|
||
"oneOf": [
|
||
{
|
||
"description": "Don't export traces",
|
||
"type": "string",
|
||
"const": "none"
|
||
},
|
||
{
|
||
"description": "Export traces to the standard output. Only useful for debugging",
|
||
"type": "string",
|
||
"const": "stdout"
|
||
},
|
||
{
|
||
"description": "Export traces to an OpenTelemetry protocol compatible endpoint",
|
||
"type": "string",
|
||
"const": "otlp"
|
||
}
|
||
]
|
||
},
|
||
"Propagator": {
|
||
"description": "Propagation format for incoming and outgoing requests",
|
||
"oneOf": [
|
||
{
|
||
"description": "Propagate according to the W3C Trace Context specification",
|
||
"type": "string",
|
||
"const": "tracecontext"
|
||
},
|
||
{
|
||
"description": "Propagate according to the W3C Baggage specification",
|
||
"type": "string",
|
||
"const": "baggage"
|
||
},
|
||
{
|
||
"description": "Propagate trace context with Jaeger compatible headers",
|
||
"type": "string",
|
||
"const": "jaeger"
|
||
}
|
||
]
|
||
},
|
||
"MetricsConfig": {
|
||
"description": "Configuration related to exporting metrics",
|
||
"type": "object",
|
||
"properties": {
|
||
"exporter": {
|
||
"description": "Exporter to use when exporting metrics",
|
||
"default": "none",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/MetricsExporterKind"
|
||
}
|
||
]
|
||
},
|
||
"endpoint": {
|
||
"description": "OTLP exporter: OTLP over HTTP compatible endpoint",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri",
|
||
"default": "https://localhost:4318"
|
||
}
|
||
}
|
||
},
|
||
"MetricsExporterKind": {
|
||
"description": "Exporter to use when exporting metrics",
|
||
"oneOf": [
|
||
{
|
||
"description": "Don't export metrics",
|
||
"type": "string",
|
||
"const": "none"
|
||
},
|
||
{
|
||
"description": "Export metrics to stdout. Only useful for debugging",
|
||
"type": "string",
|
||
"const": "stdout"
|
||
},
|
||
{
|
||
"description": "Export metrics to an OpenTelemetry protocol compatible endpoint",
|
||
"type": "string",
|
||
"const": "otlp"
|
||
},
|
||
{
|
||
"description": "Export metrics via Prometheus. An HTTP listener with the `prometheus`\nresource must be setup to expose the Promethes metrics.",
|
||
"type": "string",
|
||
"const": "prometheus"
|
||
}
|
||
]
|
||
},
|
||
"SentryConfig": {
|
||
"description": "Configuration related to the Sentry integration",
|
||
"type": "object",
|
||
"properties": {
|
||
"dsn": {
|
||
"description": "Sentry DSN",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri",
|
||
"examples": [
|
||
"https://public@host:port/1"
|
||
]
|
||
},
|
||
"environment": {
|
||
"description": "Environment to use when sending events to Sentry\n\nDefaults to `production` if not set.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"examples": [
|
||
"production"
|
||
]
|
||
},
|
||
"sample_rate": {
|
||
"description": "Sample rate for event submissions\n\nDefaults to `1.0` if not set.",
|
||
"type": [
|
||
"number",
|
||
"null"
|
||
],
|
||
"format": "float",
|
||
"examples": [
|
||
0.5
|
||
],
|
||
"minimum": 0.0,
|
||
"maximum": 1.0
|
||
},
|
||
"traces_sample_rate": {
|
||
"description": "Sample rate for tracing transactions\n\nDefaults to `0.0` if not set.",
|
||
"type": [
|
||
"number",
|
||
"null"
|
||
],
|
||
"format": "float",
|
||
"examples": [
|
||
0.5
|
||
],
|
||
"minimum": 0.0,
|
||
"maximum": 1.0
|
||
}
|
||
}
|
||
},
|
||
"TemplatesConfig": {
|
||
"description": "Configuration related to templates",
|
||
"type": "object",
|
||
"properties": {
|
||
"path": {
|
||
"description": "Path to the folder which holds the templates",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"assets_manifest": {
|
||
"description": "Path to the assets manifest",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"translations_path": {
|
||
"description": "Path to the translations",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"EmailConfig": {
|
||
"description": "Configuration related to sending emails",
|
||
"type": "object",
|
||
"properties": {
|
||
"from": {
|
||
"description": "Email address to use as From when sending emails",
|
||
"type": "string",
|
||
"format": "email",
|
||
"default": "\"Authentication Service\" <root@localhost>"
|
||
},
|
||
"reply_to": {
|
||
"description": "Email address to use as Reply-To when sending emails",
|
||
"type": "string",
|
||
"format": "email",
|
||
"default": "\"Authentication Service\" <root@localhost>"
|
||
},
|
||
"transport": {
|
||
"description": "What backend should be used when sending emails",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/EmailTransportKind"
|
||
}
|
||
]
|
||
},
|
||
"mode": {
|
||
"description": "SMTP transport: Connection mode to the relay",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/EmailSmtpMode"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"hostname": {
|
||
"description": "SMTP transport: Hostname to connect to",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/Hostname"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"port": {
|
||
"description": "SMTP transport: Port to connect to. Default is 25 for plain, 465 for TLS\nand 587 for `StartTLS`",
|
||
"type": [
|
||
"integer",
|
||
"null"
|
||
],
|
||
"format": "uint16",
|
||
"minimum": 1,
|
||
"maximum": 65535
|
||
},
|
||
"username": {
|
||
"description": "SMTP transport: Username for use to authenticate when connecting to the\nSMTP server\n\nMust be set if the `password` field is set",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"password": {
|
||
"description": "SMTP transport: Password for use to authenticate when connecting to the\nSMTP server\n\nMust be set if the `username` field is set",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"command": {
|
||
"description": "Sendmail transport: Command to use to send emails",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"default": "sendmail"
|
||
}
|
||
},
|
||
"required": [
|
||
"transport"
|
||
]
|
||
},
|
||
"EmailTransportKind": {
|
||
"description": "What backend should be used when sending emails",
|
||
"oneOf": [
|
||
{
|
||
"description": "Don't send emails anywhere",
|
||
"type": "string",
|
||
"const": "blackhole"
|
||
},
|
||
{
|
||
"description": "Send emails via an SMTP relay",
|
||
"type": "string",
|
||
"const": "smtp"
|
||
},
|
||
{
|
||
"description": "Send emails by calling sendmail",
|
||
"type": "string",
|
||
"const": "sendmail"
|
||
}
|
||
]
|
||
},
|
||
"EmailSmtpMode": {
|
||
"description": "Encryption mode to use",
|
||
"oneOf": [
|
||
{
|
||
"description": "Plain text",
|
||
"type": "string",
|
||
"const": "plain"
|
||
},
|
||
{
|
||
"description": "`StartTLS` (starts as plain text then upgrade to TLS)",
|
||
"type": "string",
|
||
"const": "starttls"
|
||
},
|
||
{
|
||
"description": "TLS",
|
||
"type": "string",
|
||
"const": "tls"
|
||
}
|
||
]
|
||
},
|
||
"SecretsConfig": {
|
||
"description": "Application secrets",
|
||
"type": "object",
|
||
"properties": {
|
||
"encryption_file": {
|
||
"description": "File containing the encryption key for secure cookies.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"encryption": {
|
||
"description": "Encryption key for secure cookies.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"examples": [
|
||
"0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff"
|
||
],
|
||
"pattern": "[0-9a-fA-F]{64}"
|
||
},
|
||
"keys": {
|
||
"description": "List of private keys to use for signing and encrypting payloads.",
|
||
"type": [
|
||
"array",
|
||
"null"
|
||
],
|
||
"items": {
|
||
"$ref": "#/definitions/KeyConfig"
|
||
}
|
||
},
|
||
"keys_dir": {
|
||
"description": "Directory of private keys to use for signing and encrypting payloads.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"KeyConfig": {
|
||
"description": "A single key with its key ID and optional password.",
|
||
"type": "object",
|
||
"properties": {
|
||
"kid": {
|
||
"description": "The key ID `kid` of the key as used by JWKs.\n\nIf not given, `kid` will be the key’s RFC 7638 JWK Thumbprint.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"password_file": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"password": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"key_file": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"key": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"PasswordsConfig": {
|
||
"description": "User password hashing config",
|
||
"type": "object",
|
||
"properties": {
|
||
"enabled": {
|
||
"description": "Whether password-based authentication is enabled",
|
||
"type": "boolean",
|
||
"default": true
|
||
},
|
||
"schemes": {
|
||
"description": "The hashing schemes to use for hashing and validating passwords\n\nThe hashing scheme with the highest version number will be used for\nhashing new passwords.",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/HashingScheme"
|
||
},
|
||
"default": [
|
||
{
|
||
"version": 1,
|
||
"algorithm": "argon2id"
|
||
}
|
||
]
|
||
},
|
||
"minimum_complexity": {
|
||
"description": "Score between 0 and 4 determining the minimum allowed password\ncomplexity. Scores are based on the ESTIMATED number of guesses\nneeded to guess the password.\n\n- 0: less than 10^2 (100)\n- 1: less than 10^4 (10'000)\n- 2: less than 10^6 (1'000'000)\n- 3: less than 10^8 (100'000'000)\n- 4: any more than that",
|
||
"type": "integer",
|
||
"format": "uint8",
|
||
"minimum": 0,
|
||
"maximum": 255,
|
||
"default": 3
|
||
}
|
||
}
|
||
},
|
||
"HashingScheme": {
|
||
"description": "Parameters for a password hashing scheme",
|
||
"type": "object",
|
||
"properties": {
|
||
"version": {
|
||
"description": "The version of the hashing scheme. They must be unique, and the highest\nversion will be used for hashing new passwords.",
|
||
"type": "integer",
|
||
"format": "uint16",
|
||
"minimum": 0,
|
||
"maximum": 65535
|
||
},
|
||
"algorithm": {
|
||
"description": "The hashing algorithm to use",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/Algorithm"
|
||
}
|
||
]
|
||
},
|
||
"unicode_normalization": {
|
||
"description": "Whether to apply Unicode normalization to the password before hashing\n\nDefaults to `false`, and generally recommended to stay false. This is\nalthough recommended when importing password hashs from Synapse, as it\napplies an NFKC normalization to the password before hashing it.",
|
||
"type": "boolean"
|
||
},
|
||
"cost": {
|
||
"description": "Cost for the bcrypt algorithm",
|
||
"type": [
|
||
"integer",
|
||
"null"
|
||
],
|
||
"format": "uint32",
|
||
"minimum": 0,
|
||
"default": 12
|
||
},
|
||
"secret": {
|
||
"description": "An optional secret to use when hashing passwords. This makes it harder\nto brute-force the passwords in case of a database leak.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"secret_file": {
|
||
"description": "Same as `secret`, but read from a file.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
},
|
||
"required": [
|
||
"version",
|
||
"algorithm"
|
||
]
|
||
},
|
||
"Algorithm": {
|
||
"description": "A hashing algorithm",
|
||
"oneOf": [
|
||
{
|
||
"description": "bcrypt",
|
||
"type": "string",
|
||
"const": "bcrypt"
|
||
},
|
||
{
|
||
"description": "argon2id",
|
||
"type": "string",
|
||
"const": "argon2id"
|
||
},
|
||
{
|
||
"description": "PBKDF2",
|
||
"type": "string",
|
||
"const": "pbkdf2"
|
||
}
|
||
]
|
||
},
|
||
"MatrixConfig": {
|
||
"description": "Configuration related to the Matrix homeserver",
|
||
"type": "object",
|
||
"properties": {
|
||
"kind": {
|
||
"description": "The kind of homeserver it is.",
|
||
"default": "synapse",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/HomeserverKind"
|
||
}
|
||
]
|
||
},
|
||
"homeserver": {
|
||
"description": "The server name of the homeserver.",
|
||
"type": "string",
|
||
"default": "localhost:8008"
|
||
},
|
||
"secret_file": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"secret": {
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"endpoint": {
|
||
"description": "The base URL of the homeserver's client API",
|
||
"type": "string",
|
||
"format": "uri",
|
||
"default": "http://localhost:8008/"
|
||
}
|
||
}
|
||
},
|
||
"HomeserverKind": {
|
||
"description": "The kind of homeserver it is.",
|
||
"oneOf": [
|
||
{
|
||
"description": "Homeserver is Synapse, version 1.135.0 or newer",
|
||
"type": "string",
|
||
"const": "synapse"
|
||
},
|
||
{
|
||
"description": "Homeserver is Synapse, version 1.135.0 or newer, in read-only mode\n\nThis is meant for testing rolling out Matrix Authentication Service with\nno risk of writing data to the homeserver.",
|
||
"type": "string",
|
||
"const": "synapse_read_only"
|
||
},
|
||
{
|
||
"description": "Homeserver is Synapse, using the legacy API",
|
||
"type": "string",
|
||
"const": "synapse_legacy"
|
||
},
|
||
{
|
||
"description": "Homeserver is Synapse, with the modern API available (>= 1.135.0)",
|
||
"type": "string",
|
||
"const": "synapse_modern"
|
||
}
|
||
]
|
||
},
|
||
"PolicyConfig": {
|
||
"description": "Application secrets",
|
||
"type": "object",
|
||
"properties": {
|
||
"wasm_module": {
|
||
"description": "Path to the WASM module",
|
||
"type": "string"
|
||
},
|
||
"client_registration_entrypoint": {
|
||
"description": "Entrypoint to use when evaluating client registrations",
|
||
"type": "string"
|
||
},
|
||
"register_entrypoint": {
|
||
"description": "Entrypoint to use when evaluating user registrations",
|
||
"type": "string"
|
||
},
|
||
"authorization_grant_entrypoint": {
|
||
"description": "Entrypoint to use when evaluating authorization grants",
|
||
"type": "string"
|
||
},
|
||
"compat_login_entrypoint": {
|
||
"description": "Entrypoint to use when evaluating compatibility logins",
|
||
"type": "string"
|
||
},
|
||
"password_entrypoint": {
|
||
"description": "Entrypoint to use when changing password",
|
||
"type": "string"
|
||
},
|
||
"email_entrypoint": {
|
||
"description": "Entrypoint to use when adding an email address",
|
||
"type": "string"
|
||
},
|
||
"data": {
|
||
"description": "Arbitrary data to pass to the policy"
|
||
}
|
||
}
|
||
},
|
||
"RateLimitingConfig": {
|
||
"description": "Configuration related to sending emails",
|
||
"type": "object",
|
||
"properties": {
|
||
"account_recovery": {
|
||
"description": "Account Recovery-specific rate limits",
|
||
"default": {
|
||
"per_ip": {
|
||
"burst": 3,
|
||
"per_second": 0.0008333333333333334
|
||
},
|
||
"per_address": {
|
||
"burst": 3,
|
||
"per_second": 0.0002777777777777778
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/AccountRecoveryRateLimitingConfig"
|
||
}
|
||
]
|
||
},
|
||
"login": {
|
||
"description": "Login-specific rate limits",
|
||
"default": {
|
||
"per_ip": {
|
||
"burst": 3,
|
||
"per_second": 0.05
|
||
},
|
||
"per_account": {
|
||
"burst": 1800,
|
||
"per_second": 0.5
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/LoginRateLimitingConfig"
|
||
}
|
||
]
|
||
},
|
||
"registration": {
|
||
"description": "Controls how many registrations attempts are permitted\nbased on source address.",
|
||
"default": {
|
||
"burst": 3,
|
||
"per_second": 0.0008333333333333334
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
},
|
||
"email_authentication": {
|
||
"description": "Email authentication-specific rate limits",
|
||
"default": {
|
||
"per_ip": {
|
||
"burst": 5,
|
||
"per_second": 0.016666666666666666
|
||
},
|
||
"per_address": {
|
||
"burst": 3,
|
||
"per_second": 0.0002777777777777778
|
||
},
|
||
"emails_per_session": {
|
||
"burst": 2,
|
||
"per_second": 0.0033333333333333335
|
||
},
|
||
"attempt_per_session": {
|
||
"burst": 10,
|
||
"per_second": 0.016666666666666666
|
||
}
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/EmailauthenticationRateLimitingConfig"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"AccountRecoveryRateLimitingConfig": {
|
||
"type": "object",
|
||
"properties": {
|
||
"per_ip": {
|
||
"description": "Controls how many account recovery attempts are permitted\nbased on source IP address.\nThis can protect against causing e-mail spam to many targets.\n\nNote: this limit also applies to re-sends.",
|
||
"default": {
|
||
"burst": 3,
|
||
"per_second": 0.0008333333333333334
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
},
|
||
"per_address": {
|
||
"description": "Controls how many account recovery attempts are permitted\nbased on the e-mail address entered into the recovery form.\nThis can protect against causing e-mail spam to one target.\n\nNote: this limit also applies to re-sends.",
|
||
"default": {
|
||
"burst": 3,
|
||
"per_second": 0.0002777777777777778
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"RateLimiterConfiguration": {
|
||
"type": "object",
|
||
"properties": {
|
||
"burst": {
|
||
"description": "A one-off burst of actions that the user can perform\nin one go without waiting.",
|
||
"type": "integer",
|
||
"format": "uint32",
|
||
"minimum": 1
|
||
},
|
||
"per_second": {
|
||
"description": "How quickly the allowance replenishes, in number of actions per second.\nCan be fractional to replenish slower.",
|
||
"type": "number",
|
||
"format": "double"
|
||
}
|
||
},
|
||
"required": [
|
||
"burst",
|
||
"per_second"
|
||
]
|
||
},
|
||
"LoginRateLimitingConfig": {
|
||
"type": "object",
|
||
"properties": {
|
||
"per_ip": {
|
||
"description": "Controls how many login attempts are permitted\nbased on source IP address.\nThis can protect against brute force login attempts.\n\nNote: this limit also applies to password checks when a user attempts to\nchange their own password.",
|
||
"default": {
|
||
"burst": 3,
|
||
"per_second": 0.05
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
},
|
||
"per_account": {
|
||
"description": "Controls how many login attempts are permitted\nbased on the account that is being attempted to be logged into.\nThis can protect against a distributed brute force attack\nbut should be set high enough to prevent someone's account being\ncasually locked out.\n\nNote: this limit also applies to password checks when a user attempts to\nchange their own password.",
|
||
"default": {
|
||
"burst": 1800,
|
||
"per_second": 0.5
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"EmailauthenticationRateLimitingConfig": {
|
||
"type": "object",
|
||
"properties": {
|
||
"per_ip": {
|
||
"description": "Controls how many email authentication attempts are permitted\nbased on the source IP address.\nThis can protect against causing e-mail spam to many targets.",
|
||
"default": {
|
||
"burst": 5,
|
||
"per_second": 0.016666666666666666
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
},
|
||
"per_address": {
|
||
"description": "Controls how many email authentication attempts are permitted\nbased on the e-mail address entered into the authentication form.\nThis can protect against causing e-mail spam to one target.\n\nNote: this limit also applies to re-sends.",
|
||
"default": {
|
||
"burst": 3,
|
||
"per_second": 0.0002777777777777778
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
},
|
||
"emails_per_session": {
|
||
"description": "Controls how many authentication emails are permitted to be sent per\nauthentication session. This ensures not too many authentication codes\nare created for the same authentication session.",
|
||
"default": {
|
||
"burst": 2,
|
||
"per_second": 0.0033333333333333335
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
},
|
||
"attempt_per_session": {
|
||
"description": "Controls how many code authentication attempts are permitted per\nauthentication session. This can protect against brute-forcing the\ncode.",
|
||
"default": {
|
||
"burst": 10,
|
||
"per_second": 0.016666666666666666
|
||
},
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/RateLimiterConfiguration"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"UpstreamOAuth2Config": {
|
||
"description": "Upstream OAuth 2.0 providers configuration",
|
||
"type": "object",
|
||
"properties": {
|
||
"providers": {
|
||
"description": "List of OAuth 2.0 providers",
|
||
"type": "array",
|
||
"items": {
|
||
"$ref": "#/definitions/Provider"
|
||
}
|
||
}
|
||
},
|
||
"required": [
|
||
"providers"
|
||
]
|
||
},
|
||
"Provider": {
|
||
"description": "Configuration for one upstream OAuth 2 provider.",
|
||
"type": "object",
|
||
"properties": {
|
||
"enabled": {
|
||
"description": "Whether this provider is enabled.\n\nDefaults to `true`",
|
||
"type": "boolean"
|
||
},
|
||
"id": {
|
||
"description": "A ULID as per https://github.com/ulid/spec",
|
||
"type": "string",
|
||
"pattern": "^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$"
|
||
},
|
||
"synapse_idp_id": {
|
||
"description": "The ID of the provider that was used by Synapse.\nIn order to perform a Synapse-to-MAS migration, this must be specified.\n\n## For providers that used OAuth 2.0 or OpenID Connect in Synapse\n\n### For `oidc_providers`:\nThis should be specified as `oidc-` followed by the ID that was\nconfigured as `idp_id` in one of the `oidc_providers` in the Synapse\nconfiguration.\nFor example, if Synapse's configuration contained `idp_id: wombat` for\nthis provider, then specify `oidc-wombat` here.\n\n### For `oidc_config` (legacy):\nSpecify `oidc` here.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"issuer": {
|
||
"description": "The OIDC issuer URL\n\nThis is required if OIDC discovery is enabled (which is the default)",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"human_name": {
|
||
"description": "A human-readable name for the provider, that will be shown to users",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"brand_name": {
|
||
"description": "A brand identifier used to customise the UI, e.g. `apple`, `google`,\n`github`, etc.\n\nValues supported by the default template are:\n\n - `apple`\n - `google`\n - `facebook`\n - `github`\n - `gitlab`\n - `twitter`\n - `discord`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"client_id": {
|
||
"description": "The client ID to use when authenticating with the provider",
|
||
"type": "string"
|
||
},
|
||
"client_secret_file": {
|
||
"description": "Path to the file containing the client secret. The client secret is used\nby the `client_secret_basic`, `client_secret_post` and\n`client_secret_jwt` authentication methods.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"client_secret": {
|
||
"description": "Alternative to `client_secret_file`: Reads the client secret directly\nfrom the config.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"token_endpoint_auth_method": {
|
||
"description": "The method to authenticate the client with the provider",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/TokenAuthMethod"
|
||
}
|
||
]
|
||
},
|
||
"sign_in_with_apple": {
|
||
"description": "Additional parameters for the `sign_in_with_apple` method",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/SignInWithApple"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"token_endpoint_auth_signing_alg": {
|
||
"description": "The JWS algorithm to use when authenticating the client with the\nprovider\n\nUsed by the `client_secret_jwt` and `private_key_jwt` methods",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/JsonWebSignatureAlg"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"id_token_signed_response_alg": {
|
||
"description": "Expected signature for the JWT payload returned by the token\nauthentication endpoint.\n\nDefaults to `RS256`.",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/JsonWebSignatureAlg"
|
||
}
|
||
]
|
||
},
|
||
"scope": {
|
||
"description": "The scopes to request from the provider\n\nDefaults to `openid`.",
|
||
"type": "string"
|
||
},
|
||
"discovery_mode": {
|
||
"description": "How to discover the provider's configuration\n\nDefaults to `oidc`, which uses OIDC discovery with strict metadata\nverification",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/DiscoveryMode"
|
||
}
|
||
]
|
||
},
|
||
"pkce_method": {
|
||
"description": "Whether to use proof key for code exchange (PKCE) when requesting and\nexchanging the token.\n\nDefaults to `auto`, which uses PKCE if the provider supports it.",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/PkceMethod"
|
||
}
|
||
]
|
||
},
|
||
"fetch_userinfo": {
|
||
"description": "Whether to fetch the user profile from the userinfo endpoint,\nor to rely on the data returned in the `id_token` from the\n`token_endpoint`.\n\nDefaults to `false`.",
|
||
"type": "boolean",
|
||
"default": false
|
||
},
|
||
"userinfo_signed_response_alg": {
|
||
"description": "Expected signature for the JWT payload returned by the userinfo\nendpoint.\n\nIf not specified, the response is expected to be an unsigned JSON\npayload.",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/JsonWebSignatureAlg"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"authorization_endpoint": {
|
||
"description": "The URL to use for the provider's authorization endpoint\n\nDefaults to the `authorization_endpoint` provided through discovery",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"userinfo_endpoint": {
|
||
"description": "The URL to use for the provider's userinfo endpoint\n\nDefaults to the `userinfo_endpoint` provided through discovery",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"token_endpoint": {
|
||
"description": "The URL to use for the provider's token endpoint\n\nDefaults to the `token_endpoint` provided through discovery",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"jwks_uri": {
|
||
"description": "The URL to use for getting the provider's public keys\n\nDefaults to the `jwks_uri` provided through discovery",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"response_mode": {
|
||
"description": "The response mode we ask the provider to use for the callback",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/ResponseMode"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"claims_imports": {
|
||
"description": "How claims should be imported from the `id_token` provided by the\nprovider",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ClaimsImports"
|
||
}
|
||
]
|
||
},
|
||
"additional_authorization_parameters": {
|
||
"description": "Additional parameters to include in the authorization request.\n\nEach value is a [`MiniJinja`] template. The template context\nexposes a `params` map containing the raw query parameters from\nthe downstream authorization request. The map is empty when the\nupstream login was not initiated by a downstream OAuth/OIDC\nauthorization request (e.g. account linking, direct login from\nthe login page).\n\n[`MiniJinja`]: https://docs.rs/minijinja\n\nTemplates that render to an empty string are dropped — so\nreferencing a downstream parameter that wasn't supplied (e.g.\n`{{ params.login_hint }}`) results in no parameter being\nforwarded, rather than an empty one.\n\nPlain strings (without `{{ … }}`) are valid templates that render\nto themselves.\n\nExample:\n\n```yaml\nadditional_authorization_parameters:\n login_hint: \"{{ params.login_hint }}\"\n acr_values: \"{{ params.acr_values }}\"\n kc_idp_hint: \"saml\"\n```\n\n`params` exposes the entire raw query string of the downstream\nrequest (including `client_id`, `state`, `code_challenge`, …).\nForward specific keys deliberately; don't blindly proxy the\nwhole map.\n\nOrder of keys is not preserved.",
|
||
"type": "object",
|
||
"additionalProperties": {
|
||
"type": "string"
|
||
}
|
||
},
|
||
"forward_login_hint": {
|
||
"description": "Whether the `login_hint` should be forwarded to the provider in the\nauthorization request.\n\nDefaults to `false`.\n\nDeprecated: prefer adding\n`login_hint: \"{{ params.login_hint }}\"` to\n`additional_authorization_parameters` instead. When this flag is\nset, a `login_hint` template entry is injected automatically if\none is not already present.",
|
||
"type": "boolean",
|
||
"default": false
|
||
},
|
||
"on_backchannel_logout": {
|
||
"description": "What to do when receiving an OIDC Backchannel logout request.\n\nDefaults to `do_nothing`.",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/OnBackchannelLogout"
|
||
}
|
||
]
|
||
},
|
||
"registration_token_required": {
|
||
"description": "Whether or not to require a registration token on `OAuth2` auth\n\nDefaults to `false`",
|
||
"type": "boolean",
|
||
"default": false
|
||
}
|
||
},
|
||
"required": [
|
||
"id",
|
||
"client_id",
|
||
"token_endpoint_auth_method"
|
||
]
|
||
},
|
||
"TokenAuthMethod": {
|
||
"description": "Authentication methods used against the OAuth 2.0 provider",
|
||
"oneOf": [
|
||
{
|
||
"description": "`none`: No authentication",
|
||
"type": "string",
|
||
"const": "none"
|
||
},
|
||
{
|
||
"description": "`client_secret_basic`: `client_id` and `client_secret` used as basic\nauthorization credentials",
|
||
"type": "string",
|
||
"const": "client_secret_basic"
|
||
},
|
||
{
|
||
"description": "`client_secret_post`: `client_id` and `client_secret` sent in the\nrequest body",
|
||
"type": "string",
|
||
"const": "client_secret_post"
|
||
},
|
||
{
|
||
"description": "`client_secret_jwt`: a `client_assertion` sent in the request body and\nsigned using the `client_secret`",
|
||
"type": "string",
|
||
"const": "client_secret_jwt"
|
||
},
|
||
{
|
||
"description": "`private_key_jwt`: a `client_assertion` sent in the request body and\nsigned by an asymmetric key",
|
||
"type": "string",
|
||
"const": "private_key_jwt"
|
||
},
|
||
{
|
||
"description": "`sign_in_with_apple`: a special method for Signin with Apple",
|
||
"type": "string",
|
||
"const": "sign_in_with_apple"
|
||
}
|
||
]
|
||
},
|
||
"SignInWithApple": {
|
||
"type": "object",
|
||
"properties": {
|
||
"private_key_file": {
|
||
"description": "The private key file used to sign the `id_token`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"private_key": {
|
||
"description": "The private key used to sign the `id_token`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"team_id": {
|
||
"description": "The Team ID of the Apple Developer Portal",
|
||
"type": "string"
|
||
},
|
||
"key_id": {
|
||
"description": "The key ID of the Apple Developer Portal",
|
||
"type": "string"
|
||
}
|
||
},
|
||
"required": [
|
||
"team_id",
|
||
"key_id"
|
||
]
|
||
},
|
||
"DiscoveryMode": {
|
||
"description": "How to discover the provider's configuration",
|
||
"oneOf": [
|
||
{
|
||
"description": "Use OIDC discovery with strict metadata verification",
|
||
"type": "string",
|
||
"const": "oidc"
|
||
},
|
||
{
|
||
"description": "Use OIDC discovery with relaxed metadata verification",
|
||
"type": "string",
|
||
"const": "insecure"
|
||
},
|
||
{
|
||
"description": "Use a static configuration",
|
||
"type": "string",
|
||
"const": "disabled"
|
||
}
|
||
]
|
||
},
|
||
"PkceMethod": {
|
||
"description": "Whether to use proof key for code exchange (PKCE) when requesting and\nexchanging the token.",
|
||
"oneOf": [
|
||
{
|
||
"description": "Use PKCE if the provider supports it\n\nDefaults to no PKCE if provider discovery is disabled",
|
||
"type": "string",
|
||
"const": "auto"
|
||
},
|
||
{
|
||
"description": "Always use PKCE with the S256 challenge method",
|
||
"type": "string",
|
||
"const": "always"
|
||
},
|
||
{
|
||
"description": "Never use PKCE",
|
||
"type": "string",
|
||
"const": "never"
|
||
}
|
||
]
|
||
},
|
||
"ResponseMode": {
|
||
"description": "The response mode we ask the provider to use for the callback",
|
||
"oneOf": [
|
||
{
|
||
"description": "`query`: The provider will send the response as a query string in the\nURL search parameters",
|
||
"type": "string",
|
||
"const": "query"
|
||
},
|
||
{
|
||
"description": "`form_post`: The provider will send the response as a POST request with\nthe response parameters in the request body\n\n<https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html>",
|
||
"type": "string",
|
||
"const": "form_post"
|
||
}
|
||
]
|
||
},
|
||
"ClaimsImports": {
|
||
"description": "How claims should be imported",
|
||
"type": "object",
|
||
"properties": {
|
||
"subject": {
|
||
"description": "How to determine the subject of the user",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/SubjectImportPreference"
|
||
}
|
||
]
|
||
},
|
||
"skip_confirmation": {
|
||
"description": "Whether to skip the interactive screen prompting the user to confirm the\nattributes that are being imported. This requires `localpart.action` to\nbe `require` and other attribute actions to be either `ignore`, `force`\nor `require`",
|
||
"type": "boolean"
|
||
},
|
||
"localpart": {
|
||
"description": "Import the localpart of the MXID",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/LocalpartImportPreference"
|
||
}
|
||
]
|
||
},
|
||
"displayname": {
|
||
"description": "Import the displayname of the user.",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/DisplaynameImportPreference"
|
||
}
|
||
]
|
||
},
|
||
"email": {
|
||
"description": "Import the email address of the user",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/EmailImportPreference"
|
||
}
|
||
]
|
||
},
|
||
"account_name": {
|
||
"description": "Set a human-readable name for the upstream account for display purposes",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/AccountNameImportPreference"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"SubjectImportPreference": {
|
||
"description": "What should be done for the subject attribute",
|
||
"type": "object",
|
||
"properties": {
|
||
"template": {
|
||
"description": "The Jinja2 template to use for the subject attribute\n\nIf not provided, the default template is `{{ user.sub }}`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"LocalpartImportPreference": {
|
||
"description": "What should be done for the localpart attribute",
|
||
"type": "object",
|
||
"properties": {
|
||
"action": {
|
||
"description": "How to handle the attribute",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ImportAction"
|
||
}
|
||
]
|
||
},
|
||
"template": {
|
||
"description": "The Jinja2 template to use for the localpart attribute\n\nIf not provided, the default template is `{{ user.preferred_username }}`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"on_conflict": {
|
||
"description": "How to handle conflicts on the claim, default value is `Fail`",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/OnConflict"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"ImportAction": {
|
||
"description": "How to handle a claim",
|
||
"oneOf": [
|
||
{
|
||
"description": "Ignore the claim",
|
||
"type": "string",
|
||
"const": "ignore"
|
||
},
|
||
{
|
||
"description": "Suggest the claim value, but allow the user to change it",
|
||
"type": "string",
|
||
"const": "suggest"
|
||
},
|
||
{
|
||
"description": "Force the claim value, but don't fail if it is missing",
|
||
"type": "string",
|
||
"const": "force"
|
||
},
|
||
{
|
||
"description": "Force the claim value, and fail if it is missing",
|
||
"type": "string",
|
||
"const": "require"
|
||
}
|
||
]
|
||
},
|
||
"OnConflict": {
|
||
"description": "How to handle an existing localpart claim",
|
||
"oneOf": [
|
||
{
|
||
"description": "Fails the upstream OAuth 2.0 login on conflict",
|
||
"type": "string",
|
||
"const": "fail"
|
||
},
|
||
{
|
||
"description": "Adds the upstream OAuth 2.0 identity link, regardless of whether there\nis an existing link or not",
|
||
"type": "string",
|
||
"const": "add"
|
||
},
|
||
{
|
||
"description": "Replace any existing upstream OAuth 2.0 identity link",
|
||
"type": "string",
|
||
"const": "replace"
|
||
},
|
||
{
|
||
"description": "Adds the upstream OAuth 2.0 identity link *only* if there is no existing\nlink for this provider on the matching user",
|
||
"type": "string",
|
||
"const": "set"
|
||
}
|
||
]
|
||
},
|
||
"DisplaynameImportPreference": {
|
||
"description": "What should be done for the displayname attribute",
|
||
"type": "object",
|
||
"properties": {
|
||
"action": {
|
||
"description": "How to handle the attribute",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ImportAction"
|
||
}
|
||
]
|
||
},
|
||
"template": {
|
||
"description": "The Jinja2 template to use for the displayname attribute\n\nIf not provided, the default template is `{{ user.name }}`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"EmailImportPreference": {
|
||
"description": "What should be done with the email attribute",
|
||
"type": "object",
|
||
"properties": {
|
||
"action": {
|
||
"description": "How to handle the claim",
|
||
"allOf": [
|
||
{
|
||
"$ref": "#/definitions/ImportAction"
|
||
}
|
||
]
|
||
},
|
||
"template": {
|
||
"description": "The Jinja2 template to use for the email address attribute\n\nIf not provided, the default template is `{{ user.email }}`",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"AccountNameImportPreference": {
|
||
"description": "What should be done for the account name attribute",
|
||
"type": "object",
|
||
"properties": {
|
||
"template": {
|
||
"description": "The Jinja2 template to use for the account name. This name is only used\nfor display purposes.\n\nIf not provided, it will be ignored.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"OnBackchannelLogout": {
|
||
"description": "What to do when receiving an OIDC Backchannel logout request.",
|
||
"oneOf": [
|
||
{
|
||
"description": "Do nothing",
|
||
"type": "string",
|
||
"const": "do_nothing"
|
||
},
|
||
{
|
||
"description": "Only log out the MAS 'browser session' started by this OIDC session",
|
||
"type": "string",
|
||
"const": "logout_browser_only"
|
||
},
|
||
{
|
||
"description": "Log out all sessions started by this OIDC session, including MAS\n'browser sessions' and client sessions",
|
||
"type": "string",
|
||
"const": "logout_all"
|
||
}
|
||
]
|
||
},
|
||
"BrandingConfig": {
|
||
"description": "Configuration section for tweaking the branding of the service",
|
||
"type": "object",
|
||
"properties": {
|
||
"service_name": {
|
||
"description": "A human-readable name. Defaults to the server's address.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"policy_uri": {
|
||
"description": "Link to a privacy policy, displayed in the footer of web pages and\nemails. It is also advertised to clients through the `op_policy_uri`\nOIDC provider metadata.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"tos_uri": {
|
||
"description": "Link to a terms of service document, displayed in the footer of web\npages and emails. It is also advertised to clients through the\n`op_tos_uri` OIDC provider metadata.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
],
|
||
"format": "uri"
|
||
},
|
||
"imprint": {
|
||
"description": "Legal imprint, displayed in the footer in the footer of web pages and\nemails.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"CaptchaConfig": {
|
||
"description": "Configuration section to setup CAPTCHA protection on a few operations",
|
||
"type": "object",
|
||
"properties": {
|
||
"service": {
|
||
"description": "Which service should be used for CAPTCHA protection",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/CaptchaServiceKind"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"site_key": {
|
||
"description": "The site key to use",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"secret_key": {
|
||
"description": "The secret key to use",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"CaptchaServiceKind": {
|
||
"description": "Which service should be used for CAPTCHA protection",
|
||
"oneOf": [
|
||
{
|
||
"description": "Use Google's reCAPTCHA v2 API",
|
||
"type": "string",
|
||
"const": "recaptcha_v2"
|
||
},
|
||
{
|
||
"description": "Use Cloudflare Turnstile",
|
||
"type": "string",
|
||
"const": "cloudflare_turnstile"
|
||
},
|
||
{
|
||
"description": "Use ``HCaptcha``",
|
||
"type": "string",
|
||
"const": "hcaptcha"
|
||
}
|
||
]
|
||
},
|
||
"AccountConfig": {
|
||
"description": "Configuration section to configure features related to account management",
|
||
"type": "object",
|
||
"properties": {
|
||
"email_change_allowed": {
|
||
"description": "Whether users are allowed to change their email addresses. Defaults to\n`true`.",
|
||
"type": "boolean"
|
||
},
|
||
"displayname_change_allowed": {
|
||
"description": "Whether users are allowed to change their display names. Defaults to\n`true`.\n\nThis should be in sync with the policy in the homeserver configuration.",
|
||
"type": "boolean"
|
||
},
|
||
"password_registration_enabled": {
|
||
"description": "Whether to enable self-service password registration. Defaults to\n`false` if password authentication is enabled.\n\nThis has no effect if password login is disabled.",
|
||
"type": "boolean"
|
||
},
|
||
"password_registration_email_required": {
|
||
"description": "Whether self-service password registrations require a valid email.\nDefaults to `true`.\n\nThis has no effect if password registration is disabled.",
|
||
"type": "boolean"
|
||
},
|
||
"password_change_allowed": {
|
||
"description": "Whether users are allowed to change their passwords. Defaults to `true`.\n\nThis has no effect if password login is disabled.",
|
||
"type": "boolean"
|
||
},
|
||
"password_recovery_enabled": {
|
||
"description": "Whether email-based password recovery is enabled. Defaults to `false`.\n\nThis has no effect if password login is disabled.",
|
||
"type": "boolean"
|
||
},
|
||
"password_registration_token_required": {
|
||
"description": "Whether registration tokens are required for password registrations.\nDefaults to `false`.\n\nWhen enabled, users must provide a valid registration token during\npassword registration. This has no effect if password registration\nis disabled.",
|
||
"type": "boolean"
|
||
},
|
||
"account_deactivation_allowed": {
|
||
"description": "Whether users are allowed to delete their own account. Defaults to\n`true`.",
|
||
"type": "boolean"
|
||
},
|
||
"login_with_email_allowed": {
|
||
"description": "Whether users can log in with their email address. Defaults to `false`.\n\nThis has no effect if password login is disabled.",
|
||
"type": "boolean"
|
||
},
|
||
"registration_token_required": {
|
||
"description": "Whether registration tokens are required for password registrations\nThis is deprecated in favor of `password_registration_token_required`",
|
||
"type": "boolean"
|
||
}
|
||
}
|
||
},
|
||
"OAuthConfig": {
|
||
"description": "Configuration section for OAuth 2.0 protocol options",
|
||
"type": "object",
|
||
"properties": {
|
||
"device_code_grant_enabled": {
|
||
"description": "Whether the Device Authorization Grant (RFC 8628) is enabled. Defaults\nto `true`.\n\nWhen disabled, the device authorization endpoint will reject requests,\nthe discovery metadata will not advertise the device authorization\nendpoint, and dynamic client registrations requesting the\n`urn:ietf:params:oauth:grant-type:device_code` grant type will be\nrejected.",
|
||
"type": "boolean"
|
||
},
|
||
"device_code_user_code_auto_fill_enabled": {
|
||
"description": "Whether the device authorization endpoint advertises a\n`verification_uri_complete` that auto-fills the user code on the\n`/link` page. Defaults to `false`.\n\nWhen disabled, the device authorization response will omit\n`verification_uri_complete`, and the `/link` route will ignore any\n`code` query parameter, forcing users to type their user code\nmanually.",
|
||
"type": "boolean"
|
||
}
|
||
}
|
||
},
|
||
"ExperimentalConfig": {
|
||
"description": "Configuration sections for experimental options\n\nDo not change these options unless you know what you are doing.",
|
||
"type": "object",
|
||
"properties": {
|
||
"access_token_ttl": {
|
||
"description": "Time-to-live of access tokens in seconds. Defaults to 5 minutes.",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 60,
|
||
"maximum": 86400
|
||
},
|
||
"compat_token_ttl": {
|
||
"description": "Time-to-live of compatibility access tokens in seconds. Defaults to 5\nminutes.",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 60,
|
||
"maximum": 86400
|
||
},
|
||
"inactive_session_expiration": {
|
||
"description": "Experimetal feature to automatically expire inactive sessions\n\nDisabled by default",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/InactiveSessionExpirationConfig"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
},
|
||
"plan_management_iframe_uri": {
|
||
"description": "Experimental feature to show a plan management tab and iframe.\nThis value is passed through \"as is\" to the client without any\nvalidation.",
|
||
"type": [
|
||
"string",
|
||
"null"
|
||
]
|
||
},
|
||
"session_limit": {
|
||
"description": "Experimental feature to limit the number of application sessions per\nuser.\n\nDisabled by default.",
|
||
"anyOf": [
|
||
{
|
||
"$ref": "#/definitions/SessionLimitConfig"
|
||
},
|
||
{
|
||
"type": "null"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"InactiveSessionExpirationConfig": {
|
||
"description": "Configuration options for the inactive session expiration feature",
|
||
"type": "object",
|
||
"properties": {
|
||
"ttl": {
|
||
"description": "Time after which an inactive session is automatically finished",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 600,
|
||
"maximum": 7776000
|
||
},
|
||
"expire_compat_sessions": {
|
||
"description": "Should compatibility sessions expire after inactivity",
|
||
"type": "boolean",
|
||
"default": true
|
||
},
|
||
"expire_oauth_sessions": {
|
||
"description": "Should OAuth 2.0 sessions expire after inactivity",
|
||
"type": "boolean",
|
||
"default": true
|
||
},
|
||
"expire_user_sessions": {
|
||
"description": "Should user sessions expire after inactivity",
|
||
"type": "boolean",
|
||
"default": true
|
||
}
|
||
},
|
||
"required": [
|
||
"ttl"
|
||
]
|
||
},
|
||
"SessionLimitConfig": {
|
||
"description": "Configuration options for the session limit feature",
|
||
"type": "object",
|
||
"properties": {
|
||
"soft_limit": {
|
||
"description": "Upon login in interactive contexts (like OAuth 2.0 sessions, or\n`m.login.sso` compatibility login flow), if the soft limit is reached,\nit will display a policy violation screen (web UI) to remove\nsessions before creating the new session.\n\nThis is not enforced in non-interactive contexts (like\n`m.login.password` login with the compatibility API) as there is no\nopportunity for us to show some UI for people remove some sessions.\nSee [`hard_limit`] for enforcement on that side.\n\nThis is the limit that is displayed in the UI\n\n[`hard_limit`]: Self::hard_limit",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 1
|
||
},
|
||
"hard_limit": {
|
||
"description": "Upon login, when `dangerous_hard_limit_eviction: false`, will refuse the\nnew login (policy violation error), otherwise, see\n[`dangerous_hard_limit_eviction`].\n\nThe hard limit is enforced in all contexts\n(interactive/non-interactive).\n\n[`dangerous_hard_limit_eviction`]: Self::dangerous_hard_limit_eviction",
|
||
"type": "integer",
|
||
"format": "uint64",
|
||
"minimum": 1
|
||
},
|
||
"max_session_threshold": {
|
||
"description": "When set, only accounts with <= `max_session_threshold` sessions have\nthe session limits applied.\n\nThis is most applicable in scenarios where your homeserver has many\nlegacy bots/scripts that login over and over (which ideally should\nbe using [personal access\ntokens](https://github.com/element-hq/matrix-authentication-service/issues/4492))\nand you want to avoid breaking their operation while maintaining some\nlevel of sanity with the number of devices that people can have.\nThis will prevent anyone else from crossing the limit.",
|
||
"type": [
|
||
"integer",
|
||
"null"
|
||
],
|
||
"format": "uint64",
|
||
"minimum": 1
|
||
},
|
||
"dangerous_hard_limit_eviction": {
|
||
"description": "Whether we should automatically choose the least recently used devices\nto remove when the [`Self::hard_limit`] is reached; in order to\nallow the new login to continue.\n\nDisabled by default\n\nWARNING: Removing sessions is a potentially damaging operation. Any\nend-to-end encrypted history on the device will be lost and can only\nbe recovered if you have another verified active device or have a\nrecovery key setup.\n\nWhen using [`dangerous_hard_limit_eviction`], the [`hard_limit`] must be\nat least 2 to avoid catastrophically losing encrypted history and\ndigital identity in pathological cases. Keep in mind this is a bare\nminimum restriction and you can still run into trouble.\n\nThis is most applicable in scenarios where your homeserver has many\nlegacy bots/scripts that login over and over (which ideally should\nbe using [personal access\ntokens](https://github.com/element-hq/matrix-authentication-service/issues/4492))\nand you want to avoid breaking their operation while maintaining some\nlevel of sanity with the number of devices that people can have.\n\nRemoving devices is a non-trivial task for some homeservers to tackle\nand can cause lots of device list changes, `/sync`, federation, and\nreplication traffic. Consider using [`max_session_threshold`] to\nlimit the size of accounts that are acted upon.\n\n[`hard_limit`]: Self::hard_limit\n[`dangerous_hard_limit_eviction`]: Self::dangerous_hard_limit_eviction\n[`max_session_threshold`]: Self::max_session_threshold",
|
||
"type": "boolean",
|
||
"default": false
|
||
}
|
||
},
|
||
"required": [
|
||
"soft_limit",
|
||
"hard_limit"
|
||
]
|
||
}
|
||
}
|
||
} |