Commit 8dcdd442 authored by Krasimir Angelov's avatar Krasimir Angelov

Add new /-/jwks route used to validate CI_JOB_JWT

Currently this routes to doorkeeper/openid_connect/discovery#keys, but
we are going to use it instead of using the existing
`/oauth/discovery/keys` directly. This way if we decide to move away
from the controller provided by `doorkeeper-openid_connect` we can do it
without disrupting any third parties using this endpoint.

Update docs to clarify that the signing key for CI_JOB_JWT may change
without any notice.
parent be9e0379
...@@ -159,6 +159,11 @@ Rails.application.routes.draw do ...@@ -159,6 +159,11 @@ Rails.application.routes.draw do
# Spam reports # Spam reports
resources :abuse_reports, only: [:new, :create] resources :abuse_reports, only: [:new, :create]
# JWKS (JSON Web Key Set) endpoint
# Used by third parties to verify CI_JOB_JWT, placeholder route
# in case we decide to move away from doorkeeper-openid_connect
get 'jwks' => 'doorkeeper/openid_connect/discovery#keys'
end end
# End of the /-/ scope. # End of the /-/ scope.
......
...@@ -47,9 +47,9 @@ The JWT's payload looks like this: ...@@ -47,9 +47,9 @@ The JWT's payload looks like this:
} }
``` ```
The JWT is encoded by using RS256 and signed with your GitLab instance's OpenID Connect private key. The expire time for the token will be set to job's timeout, if specifed, or 5 minutes if it is not. The JWT is encoded by using RS256 and signed with your GitLab instance's OpenID Connect private key. The expire time for the token will be set to job's timeout, if specifed, or 5 minutes if it is not. The key used to sign this token may change without any notice. In such case retrying the job will generate new JWT using the current signing key.
You can use this JWT and the existing JWKS endpoint (for example, `https://gitlab.example.com/oauth/discovery/keys`) to authenticate with a Vault server that is configured to allow the JWT Authentication method for authentication. You can use this JWT and your instance's JWKS endpoint (`https://gitlab.example.com/-/jwks`) to authenticate with a Vault server that is configured to allow the JWT Authentication method for authentication.
When configuring roles in Vault, you can use [bound_claims](https://www.vaultproject.io/docs/auth/jwt/#bound-claims) to match against the JWT's claims and restrict which secrets each CI job has access to. When configuring roles in Vault, you can use [bound_claims](https://www.vaultproject.io/docs/auth/jwt/#bound-claims) to match against the JWT's claims and restrict which secrets each CI job has access to.
...@@ -157,11 +157,11 @@ Now, configure the JWT Authentication method: ...@@ -157,11 +157,11 @@ Now, configure the JWT Authentication method:
```shell ```shell
$ vault write auth/jwt/config \ $ vault write auth/jwt/config \
jwks_url="https://gitlab.example.com/oauth/discovery/keys" \ jwks_url="https://gitlab.example.com/-/jwks" \
bound_issuer="gitlab.example.com" bound_issuer="gitlab.example.com"
``` ```
[bound_issuer](https://www.vaultproject.io/api/auth/jwt#inlinecode-bound_issuer) specifies that only a JWT with the issuer (that is, the `iss` claim) set to `gitlab.example.com` can use this method to authenticate, and that the JWKS endpoint (`https://gitlab.example.com/oauth/discovery/keys`) should be used to validate the token. [bound_issuer](https://www.vaultproject.io/api/auth/jwt#inlinecode-bound_issuer) specifies that only a JWT with the issuer (that is, the `iss` claim) set to `gitlab.example.com` can use this method to authenticate, and that the JWKS endpoint (`https://gitlab.example.com/-/jwks`) should be used to validate the token.
For the full list of available configuration options, see Vault's [API documentation](https://www.vaultproject.io/api/auth/jwt#configure). For the full list of available configuration options, see Vault's [API documentation](https://www.vaultproject.io/api/auth/jwt#configure).
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
require 'spec_helper' require 'spec_helper'
# oauth_discovery_keys GET /oauth/discovery/keys(.:format) doorkeeper/openid_connect/discovery#keys # oauth_discovery_keys GET /oauth/discovery/keys(.:format) doorkeeper/openid_connect/discovery#keys
# jwks GET /-/jwks(.:format) doorkeeper/openid_connect/discovery#keys
# oauth_discovery_provider GET /.well-known/openid-configuration(.:format) doorkeeper/openid_connect/discovery#provider # oauth_discovery_provider GET /.well-known/openid-configuration(.:format) doorkeeper/openid_connect/discovery#provider
# oauth_discovery_webfinger GET /.well-known/webfinger(.:format) doorkeeper/openid_connect/discovery#webfinger # oauth_discovery_webfinger GET /.well-known/webfinger(.:format) doorkeeper/openid_connect/discovery#webfinger
describe Doorkeeper::OpenidConnect::DiscoveryController, 'routing' do describe Doorkeeper::OpenidConnect::DiscoveryController, 'routing' do
...@@ -17,6 +18,10 @@ describe Doorkeeper::OpenidConnect::DiscoveryController, 'routing' do ...@@ -17,6 +18,10 @@ describe Doorkeeper::OpenidConnect::DiscoveryController, 'routing' do
it "to #keys" do it "to #keys" do
expect(get('/oauth/discovery/keys')).to route_to('doorkeeper/openid_connect/discovery#keys') expect(get('/oauth/discovery/keys')).to route_to('doorkeeper/openid_connect/discovery#keys')
end end
it "/-/jwks" do
expect(get('/-/jwks')).to route_to('doorkeeper/openid_connect/discovery#keys')
end
end end
# oauth_userinfo GET /oauth/userinfo(.:format) doorkeeper/openid_connect/userinfo#show # oauth_userinfo GET /oauth/userinfo(.:format) doorkeeper/openid_connect/userinfo#show
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment