The SPIRE OIDC Discovery Provider is a small helper that provides a minimal implementation of a subset of the OIDC discovery document as related to exposing a JSON Web Key Set (JWKS) for JSON Web Token (JWT) validation.
It provides the following endpoints:
Verb | Path | Description |
---|---|---|
GET |
/.well-known/openid-configuration |
Returns the OIDC discovery document |
GET |
/keys |
Returns the JWKS for JWT validation |
GET |
/ready |
Returns http.OK (200) as soon as requests can be served. (disabled by default) |
GET |
/live |
Returns http.OK (200) as soon as a keyset is available, otherwise http.InternalServerError (500). (disabled by default) |
The provider by default relies on ACME to obtain TLS certificates that it uses to serve the documents securely.
The provider has the following command line flags:
Flag | Description | Default |
---|---|---|
-config |
Path on disk to the HCL Configuration file | oidc-discovery-provider.conf |
The configuration file is required by the provider. It contains HCL encoded configurables.
Key | Type | Required? | Description | Default |
---|---|---|---|---|
acme |
section | required[1] | Provides the ACME configuration. | |
serving_cert_file |
section | required[1][4] | Provides the serving certificate configuration. | |
allow_insecure_scheme |
string | optional[3] | Serves OIDC configuration response with HTTP url. | false |
domains |
strings | required | One or more domains the provider is being served from. | |
experimental |
section | optional | The experimental options that are subject to change or removal. | |
insecure_addr |
string | optional[3] | Exposes the service on http. | |
set_key_use |
bool | optional | If true, the use parameter on JWKs will be set to sig . |
false |
listen_socket_path |
string | required[1][3] | Path on disk to listen with a Unix Domain Socket. Unix platforms only. | |
log_format |
string | optional | Format of the logs (either "TEXT" or "JSON" ) |
"" |
log_level |
string | required | Log level (one of "error" ,"warn" ,"info" ,"debug" ) |
"info" |
log_path |
string | optional | Path on disk to write the log. | |
log_requests |
bool | optional | If true, all HTTP requests are logged at the debug level | false |
server_api |
section | required[2] | Provides SPIRE Server API details. | |
workload_api |
section | required[2] | Provides Workload API details. | |
health_checks |
section | optional | Enable and configure health check endpoints |
experimental | Type | Required? | Description | Default |
---|---|---|---|---|
listen_named_pipe_name |
string | required[1][3] | Pipe name to listen with a named pipe. Windows only. |
[1]: One of acme
, serving_cert_file
or listen_socket_path
must be defined.
[3]: The allow_insecure_scheme
should only be used in a local development environment for testing purposes. It only works in conjunction with insecure_addr
or listen_socket_path
.
[1]: One of acme
, serving_cert_file
or listen_named_pipe_name
must be defined.
[3]: The allow_insecure_scheme
should only be used in a local development environment for testing purposes. It only works in conjunction with insecure_addr
or listen_named_pipe_name
.
[2]: One of server_api
or workload_api
must be defined. The provider relies on one of these two APIs to obtain the public key material used to construct the JWKS document.
The domains
configurable contains the list of domains the provider is
expected to be served from. If a request is received from a domain other than
one in the list (as determined by the Host or X-Forwarded-Host header), it
will be rejected. Likewise, when ACME is used, the domains
list contains the
allowed domains for which certificates will be obtained. The TLS handshake
will terminate if another domain is requested.
[4]: SPIRE OIDC Discovery provider monitors and reloads the files provided in the serving_cert_file
configuration at runtime.
Key | Type | Required? | Description | Default |
---|---|---|---|---|
cache_dir |
string | optional | The directory used to cache the ACME-obtained credentials. Disabled if explicitly set to the empty string | "./.acme-cache" |
directory_url |
string | optional | The ACME directory URL to use. Uses Let's Encrypt if unset. | "https://acme-v01.api.letsencrypt.org/directory" |
email |
string | required | The email address used to register with the ACME service | |
tos_accepted |
bool | required | Indicates explicit acceptance of the ACME service Terms of Service. Must be true. |
Key | Type | Required? | Description | Default |
---|---|---|---|---|
cert_file_path |
string | required | The certificate file path, the file must contain PEM encoded data. | |
key_file_path |
string | required | The private key file path, the file must contain PEM encoded data. | |
file_sync_interval |
duration | optional | Controls how frequently the service polls the files for changes. | 1 minute |
addr |
string | optional | Exposes the service on the given address. | :443 |
Key | Type | Required? | Description | Default |
---|---|---|---|---|
address |
string | required | SPIRE Server API gRPC target address. Only the unix name system is supported. See https://github.com/grpc/grpc/blob/master/doc/naming.md. Unix platforms only. | |
experimental |
section | optional | The experimental options that are subject to change or removal. | |
poll_interval |
duration | optional | How often to poll for changes to the public key material. | "10s" |
experimental | Type | Required? | Description | Default |
---|---|---|---|---|
named_pipe_name |
string | required | Pipe name of the SPIRE Server API named pipe. Windows only. |
Key | Type | Required? | Description | Default |
---|---|---|---|---|
experimental |
section | optional | The experimental options that are subject to change or removal. | |
socket_path |
string | required | Path on disk to the Workload API Unix Domain socket. Unix platforms only. | |
poll_interval |
duration | optional | How often to poll for changes to the public key material. | "10s" |
trust_domain |
string | required | Trust domain of the workload. This is used to pick the bundle out of the Workload API response. |
experimental | Description | Default |
---|---|---|
named_pipe_name |
Pipe name of the Workload API named pipe. Windows only. |
Health checks are enabled by adding health_checks {}
to the configuration.
The health checks endpoints are hosted on a dedicated listener on localhost.
- The "ready" state is determined by the availability of keys fetched via the workload/server API. If the keys where fetched successfully but can't be fetched anymore (e.g. workload or server API can't be reached), the server is still determined ready for the threshold interval.
- The "live" state is either determined by the availability of keys fetched via the workload/server API or the threshold interval after the server started serving requests. If the keys where fetched successfully but can't be fetched anymore (e.g. workload/server API can't be reached), the server is still determined live for the threshold interval.
The threshold interval is currently set to 5 times the workload/server APIs poll interval, but at least 3 minutes. Both states respond with a 200 OK status code for success or 500 Internal Server Error for failure.
Key | Type | Required? | Description | Default |
---|---|---|---|---|
bind_port |
string | optional | override default listener bind port | "8008" |
ready_path |
string | optional | override default ready path | "/ready" |
live_path |
string | optional | override default live path | "/live" |
log_level = "debug"
domains = ["mypublicdomain.test"]
acme {
cache_dir = "/some/path/on/disk/to/cache/creds"
email = "email@domain.test"
tos_accepted = true
}
server_api {
address = "unix:///tmp/spire-server/private/api.sock"
}
log_level = "debug"
domains = ["mypublicdomain.test"]
acme {
cache_dir = "/some/path/on/disk/to/cache/creds"
email = "email@domain.test"
tos_accepted = true
}
workload_api {
socket_path = "/tmp/spire-agent/public/api.sock"
trust_domain = "domain.test"
}
log_level = "debug"
domains = ["mypublicdomain.test"]
serving_cert_file {
cert_file_path = "/some/path/on/disk/to/cert.pem"
key_file_path = "/some/path/on/disk/to/key.pem"
}
server_api {
address = "unix:///tmp/spire-server/private/api.sock"
}
log_level = "debug"
domains = ["mypublicdomain.test"]
serving_cert_file {
cert_file_path = "/some/path/on/disk/to/cert.pem"
key_file_path = "/some/path/on/disk/to/key.pem"
}
workload_api {
socket_path = "/tmp/spire-agent/public/api.sock"
trust_domain = "domain.test"
}
The following configuration has the OIDC Discovery Provider listen for requests on the given socket. This can be used in conjunction with a webserver like Nginx, Apache, or Envoy which supports reverse proxying to a unix socket.
log_level = "debug"
domains = ["mypublicdomain.test"]
listen_socket_path = "/run/oidc-discovery-provider/server.sock"
workload_api {
socket_path = "/tmp/spire-agent/private/api.sock"
trust_domain = "domain.test"
}
A minimal Nginx configuration that proxies all traffic to the OIDC Discovery Provider's socket might look like this.
daemon off;
events {}
http {
access_log /dev/stdout;
upstream oidc {
server unix:/run/oidc-discovery-provider/server.sock;
}
server {
# ... Any TLS and listening config you may need
location / {
proxy_pass http://oidc;
}
}
}
log_level = "debug"
domains = ["mypublicdomain.test"]
acme {
cache_dir = "c:\\some\\path\\on\\disk\\to\\cache\\creds"
email = "email@domain.test"
tos_accepted = true
}
server_api {
experimental {
named_pipe_name = "\\spire-server\\private\\api"
}
}
log_level = "debug"
domains = ["mypublicdomain.test"]
acme {
cache_dir = "c:\\some\\path\\on\\disk\\to\\cache\\creds"
email = "email@domain.test"
tos_accepted = true
}
workload_api {
experimental {
named_pipe_name = "\\spire-agent\\public\\api"
}
trust_domain = "domain.test"
}
log_level = "debug"
domains = ["mypublicdomain.test"]
serving_cert_file {
cert_file_path = "c:\\some\\path\\on\\disk\\to\\cert.pem"
key_file_path = "c:\\some\\path\\on\\disk\\to\\key.pem"
}
server_api {
experimental {
named_pipe_name = "\\spire-server\\private\\api"
}
}
log_level = "debug"
domains = ["mypublicdomain.test"]
serving_cert_file {
cert_file_path = "c:\\some\\path\\on\\disk\\to\\cert.pem"
key_file_path = "c:\\some\\path\\on\\disk\\to\\key.pem"
}
workload_api {
experimental {
named_pipe_name = "\\spire-agent\\public\\api"
}
trust_domain = "domain.test"
}
The following configuration has the OIDC Discovery Provider listen for requests on the given named pipe. This can be used in conjunction with a webserver that supports reverse proxying to a named pipe.
log_level = "debug"
domains = ["mypublicdomain.test"]
experimental {
listen_named_pipe_name = "oidc-discovery-provider"
}
workload_api {
experimental {
named_pipe_name = "\\spire-agent\\public\\api"
}
trust_domain = "domain.test"
}