mirror of
https://github.com/pomerium/pomerium.git
synced 2025-04-30 02:46:30 +02:00
stub out HPKE public key fetch for self-hosted authenticate (#4360)
Fetch the HPKE public key only when configured to use the hosted authenticate service. Determine whether we are using the hosted authenticate service by comparing the resolved authenticate domain with a hard-coded list of hosted authenticate domains. Extract this list of hosted authenticate domains to the internal/urlutil package in order to keep a single source of truth for this data.
This commit is contained in:
parent
4674b98cfb
commit
a1388592d8
6 changed files with 107 additions and 6 deletions
|
@ -237,10 +237,22 @@ func (cfg *Config) GetAuthenticateKeyFetcher() (hpke.KeyFetcher, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
jwksURL := authenticateURL.ResolveReference(&url.URL{
|
|
||||||
|
// For hosted authenticate, we need to fetch the HPKE public key.
|
||||||
|
if urlutil.IsHostedAuthenticateDomain(authenticateURL.Hostname()) {
|
||||||
|
hpkeURL := authenticateURL.ResolveReference(&url.URL{
|
||||||
Path: urlutil.HPKEPublicKeyPath,
|
Path: urlutil.HPKEPublicKeyPath,
|
||||||
}).String()
|
}).String()
|
||||||
return hpke.NewKeyFetcher(jwksURL, transport), nil
|
return hpke.NewKeyFetcher(hpkeURL, transport), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise we can use our own HPKE public key.
|
||||||
|
privKey, err := cfg.Options.GetHPKEPrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pubKey := privKey.PublicKey()
|
||||||
|
return hpke.NewStubKeyFetcher(pubKey), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *Config) resolveAuthenticateURL() (*url.URL, *http.Transport, error) {
|
func (cfg *Config) resolveAuthenticateURL() (*url.URL, *http.Transport, error) {
|
||||||
|
|
|
@ -458,8 +458,9 @@ func sourceHostnames(cfg *config.Config) []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove any hosted authenticate URLs
|
// remove any hosted authenticate URLs
|
||||||
delete(dedupe, "authenticate.pomerium.app")
|
for _, domain := range urlutil.HostedAuthenticateDomains {
|
||||||
delete(dedupe, "authenticate.staging.pomerium.app")
|
delete(dedupe, domain)
|
||||||
|
}
|
||||||
|
|
||||||
var h []string
|
var h []string
|
||||||
for k := range dedupe {
|
for k := range dedupe {
|
||||||
|
|
25
internal/urlutil/hostedauthenticate.go
Normal file
25
internal/urlutil/hostedauthenticate.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package urlutil
|
||||||
|
|
||||||
|
// HostedAuthenticateDomains is a list of all known domains associated with the
|
||||||
|
// hosted authenticate service.
|
||||||
|
var HostedAuthenticateDomains = []string{
|
||||||
|
"authenticate.pomerium.app",
|
||||||
|
"authenticate.staging.pomerium.app",
|
||||||
|
}
|
||||||
|
|
||||||
|
var hostedAuthenticateDomainSet = initHostedAuthenticateDomainSet()
|
||||||
|
|
||||||
|
func initHostedAuthenticateDomainSet() map[string]struct{} {
|
||||||
|
s := make(map[string]struct{})
|
||||||
|
for _, domain := range HostedAuthenticateDomains {
|
||||||
|
s[domain] = struct{}{}
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsHostedAuthenticateDomain indicates whether the given domain is associated
|
||||||
|
// with the hosted authenticate service.
|
||||||
|
func IsHostedAuthenticateDomain(domain string) bool {
|
||||||
|
_, isHostedAuthenticate := hostedAuthenticateDomainSet[domain]
|
||||||
|
return isHostedAuthenticate
|
||||||
|
}
|
19
internal/urlutil/hostedauthenticate_test.go
Normal file
19
internal/urlutil/hostedauthenticate_test.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package urlutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIsHostedAuthenticateDomain(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, domain := range HostedAuthenticateDomains {
|
||||||
|
assert.True(t, IsHostedAuthenticateDomain(domain), domain)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, domain := range []string{"authenticate.example.com", "foo.bar"} {
|
||||||
|
assert.False(t, IsHostedAuthenticateDomain(domain), domain)
|
||||||
|
}
|
||||||
|
}
|
18
pkg/hpke/stub.go
Normal file
18
pkg/hpke/stub.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package hpke
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type stubFetcher struct {
|
||||||
|
key *PublicKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f stubFetcher) FetchPublicKey(_ context.Context) (*PublicKey, error) {
|
||||||
|
return f.key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStubKeyFetcher returns a new KeyFetcher which returns a fixed key.
|
||||||
|
func NewStubKeyFetcher(key *PublicKey) KeyFetcher {
|
||||||
|
return stubFetcher{key}
|
||||||
|
}
|
26
pkg/hpke/stub_test.go
Normal file
26
pkg/hpke/stub_test.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package hpke_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/pomerium/pomerium/pkg/hpke"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestStubFetcher(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
hpkePrivateKey, err := hpke.GeneratePrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := hpkePrivateKey.PublicKey()
|
||||||
|
|
||||||
|
f := hpke.NewStubKeyFetcher(expected)
|
||||||
|
|
||||||
|
actual, err := f.FetchPublicKey(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, expected.String(), actual.String())
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue