mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-08 05:42:47 +02:00
Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
|
ed8c5d6999 | ||
|
c0848eecfe | ||
|
618ab8fe3f | ||
|
b139c4f425 | ||
|
dcb10b1727 | ||
|
839bedac80 | ||
|
cc22174159 | ||
|
a078f93986 | ||
|
98a5779d77 | ||
|
03064fae31 | ||
|
c8ad4c054d | ||
|
e23caa50cf |
97 changed files with 1530 additions and 1025 deletions
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
|
@ -28,7 +28,7 @@ jobs:
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
|
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
node-version: 22.x
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
|
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
|
||||||
|
|
|
@ -10,8 +10,8 @@ import (
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/atomicutil"
|
"github.com/pomerium/pomerium/internal/atomicutil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,11 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/middleware"
|
"github.com/pomerium/pomerium/internal/middleware"
|
||||||
"github.com/pomerium/pomerium/internal/sessions"
|
"github.com/pomerium/pomerium/internal/sessions"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/identity"
|
"github.com/pomerium/pomerium/pkg/identity"
|
||||||
"github.com/pomerium/pomerium/pkg/identity/oidc"
|
"github.com/pomerium/pomerium/pkg/identity/oidc"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler returns the authenticate service's handler chain.
|
// Handler returns the authenticate service's handler chain.
|
||||||
|
|
|
@ -19,10 +19,10 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/atomicutil"
|
"github.com/pomerium/pomerium/internal/atomicutil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||||
"github.com/pomerium/pomerium/pkg/storage"
|
"github.com/pomerium/pomerium/pkg/storage"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Authorize struct holds
|
// Authorize struct holds
|
||||||
|
@ -149,6 +149,7 @@ func newPolicyEvaluator(
|
||||||
evaluator.WithGoogleCloudServerlessAuthenticationServiceAccount(opts.GetGoogleCloudServerlessAuthenticationServiceAccount()),
|
evaluator.WithGoogleCloudServerlessAuthenticationServiceAccount(opts.GetGoogleCloudServerlessAuthenticationServiceAccount()),
|
||||||
evaluator.WithJWTClaimsHeaders(opts.JWTClaimsHeaders),
|
evaluator.WithJWTClaimsHeaders(opts.JWTClaimsHeaders),
|
||||||
evaluator.WithJWTGroupsFilter(opts.JWTGroupsFilter),
|
evaluator.WithJWTGroupsFilter(opts.JWTGroupsFilter),
|
||||||
|
evaluator.WithDefaultJWTIssuerFormat(opts.JWTIssuerFormat),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ type evaluatorConfig struct {
|
||||||
GoogleCloudServerlessAuthenticationServiceAccount string
|
GoogleCloudServerlessAuthenticationServiceAccount string
|
||||||
JWTClaimsHeaders config.JWTClaimHeaders
|
JWTClaimsHeaders config.JWTClaimHeaders
|
||||||
JWTGroupsFilter config.JWTGroupsFilter
|
JWTGroupsFilter config.JWTGroupsFilter
|
||||||
|
DefaultJWTIssuerFormat config.JWTIssuerFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
// cacheKey() returns a hash over the configuration, except for the policies.
|
// cacheKey() returns a hash over the configuration, except for the policies.
|
||||||
|
@ -105,3 +106,10 @@ func WithJWTGroupsFilter(groups config.JWTGroupsFilter) Option {
|
||||||
cfg.JWTGroupsFilter = groups
|
cfg.JWTGroupsFilter = groups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithDefaultJWTIssuerFormat sets the default JWT issuer format in the config.
|
||||||
|
func WithDefaultJWTIssuerFormat(format config.JWTIssuerFormat) Option {
|
||||||
|
return func(cfg *evaluatorConfig) {
|
||||||
|
cfg.DefaultJWTIssuerFormat = format
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/errgrouputil"
|
"github.com/pomerium/pomerium/internal/errgrouputil"
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/contextutil"
|
"github.com/pomerium/pomerium/pkg/contextutil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/policy/criteria"
|
"github.com/pomerium/pomerium/pkg/policy/criteria"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Request contains the inputs needed for evaluation.
|
// Request contains the inputs needed for evaluation.
|
||||||
|
@ -332,6 +332,7 @@ func updateStore(ctx context.Context, store *store.Store, cfg *evaluatorConfig)
|
||||||
)
|
)
|
||||||
store.UpdateJWTClaimHeaders(cfg.JWTClaimsHeaders)
|
store.UpdateJWTClaimHeaders(cfg.JWTClaimsHeaders)
|
||||||
store.UpdateJWTGroupsFilter(cfg.JWTGroupsFilter)
|
store.UpdateJWTGroupsFilter(cfg.JWTGroupsFilter)
|
||||||
|
store.UpdateDefaultJWTIssuerFormat(cfg.DefaultJWTIssuerFormat)
|
||||||
store.UpdateRoutePolicies(cfg.Policies)
|
store.UpdateRoutePolicies(cfg.Policies)
|
||||||
store.UpdateSigningKey(jwk)
|
store.UpdateSigningKey(jwk)
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/authorize/internal/store"
|
"github.com/pomerium/pomerium/authorize/internal/store"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HeadersResponse is the output from the headers.rego script.
|
// HeadersResponse is the output from the headers.rego script.
|
||||||
|
|
|
@ -247,18 +247,16 @@ func (e *headersEvaluatorEvaluation) getGroupIDs(ctx context.Context) []string {
|
||||||
return make([]string, 0)
|
return make([]string, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *headersEvaluatorEvaluation) getJWTPayloadIss() (string, error) {
|
func (e *headersEvaluatorEvaluation) getJWTPayloadIss() string {
|
||||||
var issuerFormat string
|
issuerFormat := e.evaluator.store.GetDefaultJWTIssuerFormat()
|
||||||
if e.request.Policy != nil {
|
if e.request.Policy != nil && e.request.Policy.JWTIssuerFormat != "" {
|
||||||
issuerFormat = e.request.Policy.JWTIssuerFormat
|
issuerFormat = e.request.Policy.JWTIssuerFormat
|
||||||
}
|
}
|
||||||
switch issuerFormat {
|
switch issuerFormat {
|
||||||
case "uri":
|
case config.JWTIssuerFormatURI:
|
||||||
return fmt.Sprintf("https://%s/", e.request.HTTP.Hostname), nil
|
return fmt.Sprintf("https://%s/", e.request.HTTP.Hostname)
|
||||||
case "", "hostOnly":
|
|
||||||
return e.request.HTTP.Hostname, nil
|
|
||||||
default:
|
default:
|
||||||
return "", fmt.Errorf("unsupported JWT issuer format: %s", issuerFormat)
|
return e.request.HTTP.Hostname
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,14 +410,9 @@ func (e *headersEvaluatorEvaluation) getJWTPayload(ctx context.Context) (map[str
|
||||||
return e.cachedJWTPayload, nil
|
return e.cachedJWTPayload, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
iss, err := e.getJWTPayloadIss()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
e.gotJWTPayload = true
|
e.gotJWTPayload = true
|
||||||
e.cachedJWTPayload = map[string]any{
|
e.cachedJWTPayload = map[string]any{
|
||||||
"iss": iss,
|
"iss": e.getJWTPayloadIss(),
|
||||||
"aud": e.getJWTPayloadAud(),
|
"aud": e.getJWTPayloadAud(),
|
||||||
"jti": e.getJWTPayloadJTI(),
|
"jti": e.getJWTPayloadJTI(),
|
||||||
"iat": e.getJWTPayloadIAT(),
|
"iat": e.getJWTPayloadIAT(),
|
||||||
|
|
|
@ -437,34 +437,59 @@ func TestHeadersEvaluator(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "u1@example.com", output.Headers.Get("X-Pomerium-Claim-Email"))
|
assert.Equal(t, "u1@example.com", output.Headers.Get("X-Pomerium-Claim-Email"))
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("issuer format", func(t *testing.T) {
|
func TestHeadersEvaluator_JWTIssuerFormat(t *testing.T) {
|
||||||
t.Parallel()
|
privateJWK, _ := newJWK(t)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
store := store.New()
|
||||||
format string
|
store.UpdateSigningKey(privateJWK)
|
||||||
input string
|
|
||||||
output string
|
eval := func(_ *testing.T, input *Request) (*HeadersResponse, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
e := NewHeadersEvaluator(store)
|
||||||
|
return e.Evaluate(ctx, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname := "route.example.com"
|
||||||
|
|
||||||
|
cases := []struct {
|
||||||
|
globalFormat config.JWTIssuerFormat
|
||||||
|
routeFormat config.JWTIssuerFormat
|
||||||
|
expected string
|
||||||
}{
|
}{
|
||||||
{"", "example.com", "example.com"},
|
{"", "", "route.example.com"},
|
||||||
{"hostOnly", "host-only.example.com", "host-only.example.com"},
|
{"hostOnly", "", "route.example.com"},
|
||||||
{"uri", "uri.example.com", "https://uri.example.com/"},
|
{"uri", "", "https://route.example.com/"},
|
||||||
} {
|
|
||||||
|
{"", "hostOnly", "route.example.com"},
|
||||||
|
{"hostOnly", "hostOnly", "route.example.com"},
|
||||||
|
{"uri", "hostOnly", "route.example.com"},
|
||||||
|
|
||||||
|
{"", "uri", "https://route.example.com/"},
|
||||||
|
{"hostOnly", "uri", "https://route.example.com/"},
|
||||||
|
{"uri", "uri", "https://route.example.com/"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
t.Run("", func(t *testing.T) {
|
||||||
|
store.UpdateDefaultJWTIssuerFormat(tc.globalFormat)
|
||||||
output, err := eval(t,
|
output, err := eval(t,
|
||||||
nil,
|
|
||||||
&Request{
|
&Request{
|
||||||
HTTP: RequestHTTP{
|
HTTP: RequestHTTP{
|
||||||
Hostname: tc.input,
|
Hostname: hostname,
|
||||||
},
|
},
|
||||||
Policy: &config.Policy{
|
Policy: &config.Policy{
|
||||||
JWTIssuerFormat: tc.format,
|
JWTIssuerFormat: tc.routeFormat,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
m := decodeJWTAssertion(t, output.Headers)
|
m := decodeJWTAssertion(t, output.Headers)
|
||||||
assert.Equal(t, tc.output, m["iss"], "unexpected issuer for format=%s", tc.format)
|
assert.Equal(t, tc.expected, m["iss"],
|
||||||
}
|
"unexpected issuer for global format=%q, route format=%q",
|
||||||
|
tc.globalFormat, tc.routeFormat)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHeadersEvaluator_JWTGroupsFilter(t *testing.T) {
|
func TestHeadersEvaluator_JWTGroupsFilter(t *testing.T) {
|
||||||
|
|
|
@ -11,11 +11,11 @@ import (
|
||||||
"github.com/pomerium/pomerium/authorize/internal/store"
|
"github.com/pomerium/pomerium/authorize/internal/store"
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/contextutil"
|
"github.com/pomerium/pomerium/pkg/contextutil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/policy"
|
"github.com/pomerium/pomerium/pkg/policy"
|
||||||
"github.com/pomerium/pomerium/pkg/policy/criteria"
|
"github.com/pomerium/pomerium/pkg/policy/criteria"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PolicyRequest is the input to policy evaluation.
|
// PolicyRequest is the input to policy evaluation.
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -54,8 +55,11 @@ func (a *Authorize) Check(ctx context.Context, in *envoy_service_auth_v3.CheckRe
|
||||||
|
|
||||||
// load the session
|
// load the session
|
||||||
s, err := a.loadSession(ctx, hreq, req)
|
s, err := a.loadSession(ctx, hreq, req)
|
||||||
if err != nil {
|
if errors.Is(err, sessions.ErrInvalidSession) {
|
||||||
return nil, err
|
// ENG-2172: if this is an invalid session, don't evaluate policy, return forbidden
|
||||||
|
return a.deniedResponse(ctx, in, int32(http.StatusForbidden), http.StatusText(http.StatusForbidden), nil)
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, fmt.Errorf("error loading session: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if there's a session or service account, load the user
|
// if there's a session or service account, load the user
|
||||||
|
@ -122,6 +126,7 @@ func (a *Authorize) loadSession(
|
||||||
Str("request-id", requestID).
|
Str("request-id", requestID).
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("error creating session for incoming idp token")
|
Msg("error creating session for incoming idp token")
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionState, _ := a.state.Load().sessionStore.LoadSessionStateAndCheckIDP(hreq)
|
sessionState, _ := a.state.Load().sessionStore.LoadSessionStateAndCheckIDP(hreq)
|
||||||
|
|
|
@ -21,9 +21,9 @@ import (
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||||
"github.com/pomerium/pomerium/pkg/storage"
|
"github.com/pomerium/pomerium/pkg/storage"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Store stores data for the OPA rego policy evaluation.
|
// A Store stores data for the OPA rego policy evaluation.
|
||||||
|
@ -33,6 +33,7 @@ type Store struct {
|
||||||
googleCloudServerlessAuthenticationServiceAccount atomic.Pointer[string]
|
googleCloudServerlessAuthenticationServiceAccount atomic.Pointer[string]
|
||||||
jwtClaimHeaders atomic.Pointer[map[string]string]
|
jwtClaimHeaders atomic.Pointer[map[string]string]
|
||||||
jwtGroupsFilter atomic.Pointer[config.JWTGroupsFilter]
|
jwtGroupsFilter atomic.Pointer[config.JWTGroupsFilter]
|
||||||
|
defaultJWTIssuerFormat atomic.Pointer[config.JWTIssuerFormat]
|
||||||
signingKey atomic.Pointer[jose.JSONWebKey]
|
signingKey atomic.Pointer[jose.JSONWebKey]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +67,13 @@ func (s *Store) GetJWTGroupsFilter() config.JWTGroupsFilter {
|
||||||
return config.JWTGroupsFilter{}
|
return config.JWTGroupsFilter{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Store) GetDefaultJWTIssuerFormat() config.JWTIssuerFormat {
|
||||||
|
if f := s.defaultJWTIssuerFormat.Load(); f != nil {
|
||||||
|
return *f
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Store) GetSigningKey() *jose.JSONWebKey {
|
func (s *Store) GetSigningKey() *jose.JSONWebKey {
|
||||||
return s.signingKey.Load()
|
return s.signingKey.Load()
|
||||||
}
|
}
|
||||||
|
@ -89,6 +97,12 @@ func (s *Store) UpdateJWTGroupsFilter(groups config.JWTGroupsFilter) {
|
||||||
s.jwtGroupsFilter.Store(&groups)
|
s.jwtGroupsFilter.Store(&groups)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateDefaultJWTIssuerFormat updates the JWT groups filter in the store.
|
||||||
|
func (s *Store) UpdateDefaultJWTIssuerFormat(format config.JWTIssuerFormat) {
|
||||||
|
// This isn't used by the Rego code, so we don't need to write it to the opastorage.Store instance.
|
||||||
|
s.defaultJWTIssuerFormat.Store(&format)
|
||||||
|
}
|
||||||
|
|
||||||
// UpdateRoutePolicies updates the route policies in the store.
|
// UpdateRoutePolicies updates the route policies in the store.
|
||||||
func (s *Store) UpdateRoutePolicies(routePolicies []*config.Policy) {
|
func (s *Store) UpdateRoutePolicies(routePolicies []*config.Policy) {
|
||||||
s.write("/route_policies", routePolicies)
|
s.write("/route_policies", routePolicies)
|
||||||
|
|
|
@ -12,13 +12,13 @@ import (
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/version"
|
"github.com/pomerium/pomerium/internal/version"
|
||||||
_ "github.com/pomerium/pomerium/internal/zero/bootstrap/writers/filesystem"
|
_ "github.com/pomerium/pomerium/internal/zero/bootstrap/writers/filesystem"
|
||||||
_ "github.com/pomerium/pomerium/internal/zero/bootstrap/writers/k8s"
|
_ "github.com/pomerium/pomerium/internal/zero/bootstrap/writers/k8s"
|
||||||
zero_cmd "github.com/pomerium/pomerium/internal/zero/cmd"
|
zero_cmd "github.com/pomerium/pomerium/internal/zero/cmd"
|
||||||
"github.com/pomerium/pomerium/pkg/cmd/pomerium"
|
"github.com/pomerium/pomerium/pkg/cmd/pomerium"
|
||||||
"github.com/pomerium/pomerium/pkg/envoy/files"
|
"github.com/pomerium/pomerium/pkg/envoy/files"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/hashutil"
|
"github.com/pomerium/pomerium/internal/hashutil"
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
|
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
||||||
"github.com/pomerium/pomerium/pkg/policy/parser"
|
"github.com/pomerium/pomerium/pkg/policy/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -617,3 +618,50 @@ func (f JWTGroupsFilter) Equal(other JWTGroupsFilter) bool {
|
||||||
}
|
}
|
||||||
return f.set.Equal(other.set)
|
return f.set.Equal(other.set)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type JWTIssuerFormat string
|
||||||
|
|
||||||
|
const (
|
||||||
|
JWTIssuerFormatUnset JWTIssuerFormat = ""
|
||||||
|
JWTIssuerFormatHostOnly JWTIssuerFormat = "hostOnly"
|
||||||
|
JWTIssuerFormatURI JWTIssuerFormat = "uri"
|
||||||
|
)
|
||||||
|
|
||||||
|
var knownJWTIssuerFormats = map[JWTIssuerFormat]struct{}{
|
||||||
|
JWTIssuerFormatUnset: {},
|
||||||
|
JWTIssuerFormatHostOnly: {},
|
||||||
|
JWTIssuerFormatURI: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
func JWTIssuerFormatFromPB(format *configpb.IssuerFormat) JWTIssuerFormat {
|
||||||
|
if format == nil {
|
||||||
|
return JWTIssuerFormatUnset
|
||||||
|
}
|
||||||
|
|
||||||
|
switch *format {
|
||||||
|
case configpb.IssuerFormat_IssuerHostOnly:
|
||||||
|
return JWTIssuerFormatHostOnly
|
||||||
|
case configpb.IssuerFormat_IssuerURI:
|
||||||
|
return JWTIssuerFormatURI
|
||||||
|
default:
|
||||||
|
return JWTIssuerFormatUnset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f JWTIssuerFormat) ToPB() *configpb.IssuerFormat {
|
||||||
|
switch f {
|
||||||
|
case JWTIssuerFormatUnset:
|
||||||
|
return nil
|
||||||
|
case JWTIssuerFormatHostOnly:
|
||||||
|
return configpb.IssuerFormat_IssuerHostOnly.Enum()
|
||||||
|
case JWTIssuerFormatURI:
|
||||||
|
return configpb.IssuerFormat_IssuerURI.Enum()
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f JWTIssuerFormat) Valid() bool {
|
||||||
|
_, ok := knownJWTIssuerFormats[f]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBuilder_buildACMETLSALPNCluster(t *testing.T) {
|
func TestBuilder_buildACMETLSALPNCluster(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
b := New("local-grpc", "local-http", "local-metrics", nil, nil, true)
|
||||||
testutil.AssertProtoJSONEqual(t,
|
testutil.AssertProtoJSONEqual(t,
|
||||||
`{
|
`{
|
||||||
"name": "pomerium-acme-tls-alpn",
|
"name": "pomerium-acme-tls-alpn",
|
||||||
|
@ -34,7 +34,7 @@ func TestBuilder_buildACMETLSALPNCluster(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilder_buildACMETLSALPNFilterChain(t *testing.T) {
|
func TestBuilder_buildACMETLSALPNFilterChain(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
b := New("local-grpc", "local-http", "local-metrics", nil, nil, true)
|
||||||
testutil.AssertProtoJSONEqual(t,
|
testutil.AssertProtoJSONEqual(t,
|
||||||
`{
|
`{
|
||||||
"filterChainMatch": {
|
"filterChainMatch": {
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/config/otelconfig"
|
"github.com/pomerium/pomerium/config/otelconfig"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry"
|
"github.com/pomerium/pomerium/internal/telemetry"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
"google.golang.org/protobuf/types/known/structpb"
|
"google.golang.org/protobuf/types/known/structpb"
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
func TestBuilder_BuildBootstrapAdmin(t *testing.T) {
|
func TestBuilder_BuildBootstrapAdmin(t *testing.T) {
|
||||||
t.Setenv("TMPDIR", "/tmp")
|
t.Setenv("TMPDIR", "/tmp")
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
t.Run("valid", func(t *testing.T) {
|
t.Run("valid", func(t *testing.T) {
|
||||||
adminCfg, err := b.BuildBootstrapAdmin(&config.Config{
|
adminCfg, err := b.BuildBootstrapAdmin(&config.Config{
|
||||||
Options: &config.Options{
|
Options: &config.Options{
|
||||||
|
@ -35,7 +35,7 @@ func TestBuilder_BuildBootstrapAdmin(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilder_BuildBootstrapLayeredRuntime(t *testing.T) {
|
func TestBuilder_BuildBootstrapLayeredRuntime(t *testing.T) {
|
||||||
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
|
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil, true)
|
||||||
staticCfg, err := b.BuildBootstrapLayeredRuntime(context.Background(), &config.Config{})
|
staticCfg, err := b.BuildBootstrapLayeredRuntime(context.Background(), &config.Config{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testutil.AssertProtoJSONEqual(t, `
|
testutil.AssertProtoJSONEqual(t, `
|
||||||
|
@ -61,7 +61,7 @@ func TestBuilder_BuildBootstrapLayeredRuntime(t *testing.T) {
|
||||||
|
|
||||||
func TestBuilder_BuildBootstrapStaticResources(t *testing.T) {
|
func TestBuilder_BuildBootstrapStaticResources(t *testing.T) {
|
||||||
t.Run("valid", func(t *testing.T) {
|
t.Run("valid", func(t *testing.T) {
|
||||||
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
|
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil, true)
|
||||||
staticCfg, err := b.BuildBootstrapStaticResources(context.Background(), &config.Config{}, false)
|
staticCfg, err := b.BuildBootstrapStaticResources(context.Background(), &config.Config{}, false)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testutil.AssertProtoJSONEqual(t, `
|
testutil.AssertProtoJSONEqual(t, `
|
||||||
|
@ -105,14 +105,14 @@ func TestBuilder_BuildBootstrapStaticResources(t *testing.T) {
|
||||||
`, staticCfg)
|
`, staticCfg)
|
||||||
})
|
})
|
||||||
t.Run("bad gRPC address", func(t *testing.T) {
|
t.Run("bad gRPC address", func(t *testing.T) {
|
||||||
b := New("xyz:zyx", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
|
b := New("xyz:zyx", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil, true)
|
||||||
_, err := b.BuildBootstrapStaticResources(context.Background(), &config.Config{}, false)
|
_, err := b.BuildBootstrapStaticResources(context.Background(), &config.Config{}, false)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilder_BuildBootstrapStatsConfig(t *testing.T) {
|
func TestBuilder_BuildBootstrapStatsConfig(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
t.Run("valid", func(t *testing.T) {
|
t.Run("valid", func(t *testing.T) {
|
||||||
statsCfg, err := b.BuildBootstrapStatsConfig(&config.Config{
|
statsCfg, err := b.BuildBootstrapStatsConfig(&config.Config{
|
||||||
Options: &config.Options{
|
Options: &config.Options{
|
||||||
|
@ -132,7 +132,7 @@ func TestBuilder_BuildBootstrapStatsConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilder_BuildBootstrap(t *testing.T) {
|
func TestBuilder_BuildBootstrap(t *testing.T) {
|
||||||
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
|
b := New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil, true)
|
||||||
t.Run("OverloadManager", func(t *testing.T) {
|
t.Run("OverloadManager", func(t *testing.T) {
|
||||||
bootstrap, err := b.BuildBootstrap(context.Background(), &config.Config{
|
bootstrap, err := b.BuildBootstrap(context.Background(), &config.Config{
|
||||||
Options: &config.Options{
|
Options: &config.Options{
|
||||||
|
|
|
@ -12,6 +12,7 @@ type Builder struct {
|
||||||
localMetricsAddress string
|
localMetricsAddress string
|
||||||
filemgr *filemgr.Manager
|
filemgr *filemgr.Manager
|
||||||
reproxy *reproxy.Handler
|
reproxy *reproxy.Handler
|
||||||
|
addIPV6InternalRanges bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Builder.
|
// New creates a new Builder.
|
||||||
|
@ -21,6 +22,7 @@ func New(
|
||||||
localMetricsAddress string,
|
localMetricsAddress string,
|
||||||
fileManager *filemgr.Manager,
|
fileManager *filemgr.Manager,
|
||||||
reproxyHandler *reproxy.Handler,
|
reproxyHandler *reproxy.Handler,
|
||||||
|
addIPV6InternalRanges bool,
|
||||||
) *Builder {
|
) *Builder {
|
||||||
if reproxyHandler == nil {
|
if reproxyHandler == nil {
|
||||||
reproxyHandler = reproxy.New()
|
reproxyHandler = reproxy.New()
|
||||||
|
@ -31,5 +33,6 @@ func New(
|
||||||
localMetricsAddress: localMetricsAddress,
|
localMetricsAddress: localMetricsAddress,
|
||||||
filemgr: fileManager,
|
filemgr: fileManager,
|
||||||
reproxy: reproxyHandler,
|
reproxy: reproxyHandler,
|
||||||
|
addIPV6InternalRanges: addIPV6InternalRanges,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@ import (
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildClusters builds envoy clusters from the given config.
|
// BuildClusters builds envoy clusters from the given config.
|
||||||
|
|
|
@ -27,7 +27,7 @@ func Test_BuildClusters(t *testing.T) {
|
||||||
|
|
||||||
opts := config.NewDefaultOptions()
|
opts := config.NewDefaultOptions()
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
clusters, err := b.BuildClusters(ctx, &config.Config{Options: opts})
|
clusters, err := b.BuildClusters(ctx, &config.Config{Options: opts})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testutil.AssertProtoJSONFileEqual(t, "testdata/clusters.json", clusters)
|
testutil.AssertProtoJSONFileEqual(t, "testdata/clusters.json", clusters)
|
||||||
|
@ -38,7 +38,7 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
||||||
cacheDir, _ := os.UserCacheDir()
|
cacheDir, _ := os.UserCacheDir()
|
||||||
customCA := filepath.Join(cacheDir, "pomerium", "envoy", "files", "custom-ca-3133535332543131503345494c.pem")
|
customCA := filepath.Join(cacheDir, "pomerium", "envoy", "files", "custom-ca-3133535332543131503345494c.pem")
|
||||||
|
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
rootCABytes, _ := getCombinedCertificateAuthority(ctx, &config.Config{Options: &config.Options{}})
|
rootCABytes, _ := getCombinedCertificateAuthority(ctx, &config.Config{Options: &config.Options{}})
|
||||||
rootCA := b.filemgr.BytesDataSource("ca.pem", rootCABytes).GetFilename()
|
rootCA := b.filemgr.BytesDataSource("ca.pem", rootCABytes).GetFilename()
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ func Test_buildPolicyTransportSocket(t *testing.T) {
|
||||||
|
|
||||||
func Test_buildCluster(t *testing.T) {
|
func Test_buildCluster(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
rootCABytes, _ := getCombinedCertificateAuthority(ctx, &config.Config{Options: &config.Options{}})
|
rootCABytes, _ := getCombinedCertificateAuthority(ctx, &config.Config{Options: &config.Options{}})
|
||||||
rootCA := b.filemgr.BytesDataSource("ca.pem", rootCABytes).GetFilename()
|
rootCA := b.filemgr.BytesDataSource("ca.pem", rootCABytes).GetFilename()
|
||||||
o1 := config.NewDefaultOptions()
|
o1 := config.NewDefaultOptions()
|
||||||
|
@ -1012,7 +1012,7 @@ func Test_bindConfig(t *testing.T) {
|
||||||
ctx, clearTimeout := context.WithTimeout(context.Background(), time.Second*10)
|
ctx, clearTimeout := context.WithTimeout(context.Background(), time.Second*10)
|
||||||
defer clearTimeout()
|
defer clearTimeout()
|
||||||
|
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
t.Run("no bind config", func(t *testing.T) {
|
t.Run("no bind config", func(t *testing.T) {
|
||||||
cluster, err := b.buildPolicyCluster(ctx, &config.Config{Options: &config.Options{}}, &config.Policy{
|
cluster, err := b.buildPolicyCluster(ctx, &config.Config{Options: &config.Options{}}, &config.Policy{
|
||||||
From: "https://from.example.com",
|
From: "https://from.example.com",
|
||||||
|
|
|
@ -44,10 +44,10 @@ func ExtAuthzFilter(grpcClientTimeout *durationpb.Duration) *envoy_extensions_fi
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPConnectionManagerFilter creates a new HTTP connection manager filter.
|
// HTTPConnectionManagerFilter creates a new HTTP connection manager filter.
|
||||||
func HTTPConnectionManagerFilter(
|
func (b *Builder) HTTPConnectionManagerFilter(
|
||||||
httpConnectionManager *envoy_extensions_filters_network_http_connection_manager.HttpConnectionManager,
|
httpConnectionManager *envoy_extensions_filters_network_http_connection_manager.HttpConnectionManager,
|
||||||
) *envoy_config_listener_v3.Filter {
|
) *envoy_config_listener_v3.Filter {
|
||||||
applyGlobalHTTPConnectionManagerOptions(httpConnectionManager)
|
b.applyGlobalHTTPConnectionManagerOptions(httpConnectionManager)
|
||||||
return &envoy_config_listener_v3.Filter{
|
return &envoy_config_listener_v3.Filter{
|
||||||
Name: "envoy.filters.network.http_connection_manager",
|
Name: "envoy.filters.network.http_connection_manager",
|
||||||
ConfigType: &envoy_config_listener_v3.Filter_TypedConfig{
|
ConfigType: &envoy_config_listener_v3.Filter_TypedConfig{
|
||||||
|
|
|
@ -128,23 +128,29 @@ func (b *Builder) buildLocalReplyConfig(
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyGlobalHTTPConnectionManagerOptions(hcm *envoy_http_connection_manager.HttpConnectionManager) {
|
func (b *Builder) applyGlobalHTTPConnectionManagerOptions(hcm *envoy_http_connection_manager.HttpConnectionManager) {
|
||||||
if hcm.InternalAddressConfig == nil {
|
if hcm.InternalAddressConfig == nil {
|
||||||
// see doc comment on InternalAddressConfig for details
|
ranges := []*envoy_config_core_v3.CidrRange{
|
||||||
hcm.InternalAddressConfig = &envoy_http_connection_manager.HttpConnectionManager_InternalAddressConfig{
|
|
||||||
CidrRanges: []*envoy_config_core_v3.CidrRange{
|
|
||||||
// localhost
|
// localhost
|
||||||
{AddressPrefix: "127.0.0.1", PrefixLen: wrapperspb.UInt32(32)},
|
{AddressPrefix: "127.0.0.1", PrefixLen: wrapperspb.UInt32(32)},
|
||||||
{AddressPrefix: "::1", PrefixLen: wrapperspb.UInt32(128)},
|
|
||||||
|
|
||||||
// RFC1918
|
// RFC1918
|
||||||
{AddressPrefix: "10.0.0.0", PrefixLen: wrapperspb.UInt32(8)},
|
{AddressPrefix: "10.0.0.0", PrefixLen: wrapperspb.UInt32(8)},
|
||||||
{AddressPrefix: "192.168.0.0", PrefixLen: wrapperspb.UInt32(16)},
|
{AddressPrefix: "192.168.0.0", PrefixLen: wrapperspb.UInt32(16)},
|
||||||
{AddressPrefix: "172.16.0.0", PrefixLen: wrapperspb.UInt32(12)},
|
{AddressPrefix: "172.16.0.0", PrefixLen: wrapperspb.UInt32(12)},
|
||||||
|
}
|
||||||
|
if b.addIPV6InternalRanges {
|
||||||
|
ranges = append(ranges, []*envoy_config_core_v3.CidrRange{
|
||||||
|
// Localhost IPv6
|
||||||
|
{AddressPrefix: "::1", PrefixLen: wrapperspb.UInt32(128)},
|
||||||
// RFC4193
|
// RFC4193
|
||||||
{AddressPrefix: "fd00::", PrefixLen: wrapperspb.UInt32(8)},
|
{AddressPrefix: "fd00::", PrefixLen: wrapperspb.UInt32(8)},
|
||||||
},
|
}...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// see doc comment on InternalAddressConfig for details
|
||||||
|
hcm.InternalAddressConfig = &envoy_http_connection_manager.HttpConnectionManager_InternalAddressConfig{
|
||||||
|
CidrRanges: ranges,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
const listenerBufferLimit uint32 = 32 * 1024
|
const listenerBufferLimit uint32 = 32 * 1024
|
||||||
|
|
|
@ -51,7 +51,7 @@ func (b *Builder) buildEnvoyAdminHTTPConnectionManagerFilter() *envoy_config_lis
|
||||||
},
|
},
|
||||||
}})
|
}})
|
||||||
|
|
||||||
return HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
return b.HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
||||||
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
||||||
StatPrefix: "envoy-admin",
|
StatPrefix: "envoy-admin",
|
||||||
RouteSpecifier: &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{
|
RouteSpecifier: &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{
|
||||||
|
|
|
@ -98,7 +98,7 @@ func (b *Builder) buildGRPCHTTPConnectionManagerFilter() *envoy_config_listener_
|
||||||
Routes: routes,
|
Routes: routes,
|
||||||
}})
|
}})
|
||||||
|
|
||||||
return HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
return b.HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
||||||
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
||||||
StatPrefix: "grpc_ingress",
|
StatPrefix: "grpc_ingress",
|
||||||
// limit request first byte to last byte time
|
// limit request first byte to last byte time
|
||||||
|
|
|
@ -207,9 +207,6 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
|
||||||
mgr.CodecType = envoy_extensions_filters_network_http_connection_manager.HttpConnectionManager_AUTO
|
mgr.CodecType = envoy_extensions_filters_network_http_connection_manager.HttpConnectionManager_AUTO
|
||||||
} else if cfg.Options.GetCodecType() == config.CodecTypeAuto || cfg.Options.GetCodecType() == config.CodecTypeHTTP2 {
|
} else if cfg.Options.GetCodecType() == config.CodecTypeAuto || cfg.Options.GetCodecType() == config.CodecTypeHTTP2 {
|
||||||
mgr.CodecType = cfg.Options.GetCodecType().ToEnvoy()
|
mgr.CodecType = cfg.Options.GetCodecType().ToEnvoy()
|
||||||
mgr.Http2ProtocolOptions = &envoy_config_core_v3.Http2ProtocolOptions{
|
|
||||||
AllowConnect: true,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mgr.CodecType = cfg.Options.GetCodecType().ToEnvoy()
|
mgr.CodecType = cfg.Options.GetCodecType().ToEnvoy()
|
||||||
}
|
}
|
||||||
|
@ -236,7 +233,7 @@ func (b *Builder) buildMainHTTPConnectionManagerFilter(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTTPConnectionManagerFilter(mgr), nil
|
return b.HTTPConnectionManagerFilter(mgr), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newListenerAccessLog() *envoy_config_accesslog_v3.AccessLog {
|
func newListenerAccessLog() *envoy_config_accesslog_v3.AccessLog {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_requireProxyProtocol(t *testing.T) {
|
func Test_requireProxyProtocol(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
b := New("local-grpc", "local-http", "local-metrics", nil, nil, true)
|
||||||
t.Run("required", func(t *testing.T) {
|
t.Run("required", func(t *testing.T) {
|
||||||
li, err := b.buildMainListener(context.Background(), &config.Config{Options: &config.Options{
|
li, err := b.buildMainListener(context.Background(), &config.Config{Options: &config.Options{
|
||||||
UseProxyProtocol: true,
|
UseProxyProtocol: true,
|
||||||
|
|
|
@ -121,7 +121,7 @@ func (b *Builder) buildMetricsHTTPConnectionManagerFilter() *envoy_config_listen
|
||||||
},
|
},
|
||||||
}})
|
}})
|
||||||
|
|
||||||
return HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
return b.HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
||||||
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
||||||
StatPrefix: "metrics",
|
StatPrefix: "metrics",
|
||||||
RouteSpecifier: &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{
|
RouteSpecifier: &envoy_http_connection_manager.HttpConnectionManager_RouteConfig{
|
||||||
|
|
|
@ -51,7 +51,7 @@ func TestBuildListeners(t *testing.T) {
|
||||||
OutboundPort: "10003",
|
OutboundPort: "10003",
|
||||||
MetricsPort: "10004",
|
MetricsPort: "10004",
|
||||||
}
|
}
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
t.Run("enable grpc by default", func(t *testing.T) {
|
t.Run("enable grpc by default", func(t *testing.T) {
|
||||||
cfg := cfg.Clone()
|
cfg := cfg.Clone()
|
||||||
lis, err := b.BuildListeners(ctx, cfg, false)
|
lis, err := b.BuildListeners(ctx, cfg, false)
|
||||||
|
@ -125,7 +125,7 @@ func Test_buildMetricsHTTPConnectionManagerFilter(t *testing.T) {
|
||||||
certFileName := filepath.Join(cacheDir, "pomerium", "envoy", "files", "tls-crt-5a353247453159375849565a.pem")
|
certFileName := filepath.Join(cacheDir, "pomerium", "envoy", "files", "tls-crt-5a353247453159375849565a.pem")
|
||||||
keyFileName := filepath.Join(cacheDir, "pomerium", "envoy", "files", "tls-key-3159554e32473758435257364b.pem")
|
keyFileName := filepath.Join(cacheDir, "pomerium", "envoy", "files", "tls-key-3159554e32473758435257364b.pem")
|
||||||
|
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
li, err := b.buildMetricsListener(&config.Config{
|
li, err := b.buildMetricsListener(&config.Config{
|
||||||
Options: &config.Options{
|
Options: &config.Options{
|
||||||
MetricsAddr: "127.0.0.1:9902",
|
MetricsAddr: "127.0.0.1:9902",
|
||||||
|
@ -143,7 +143,7 @@ func Test_buildMetricsHTTPConnectionManagerFilter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_buildMainHTTPConnectionManagerFilter(t *testing.T) {
|
func Test_buildMainHTTPConnectionManagerFilter(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
b := New("local-grpc", "local-http", "local-metrics", nil, nil, true)
|
||||||
|
|
||||||
options := config.NewDefaultOptions()
|
options := config.NewDefaultOptions()
|
||||||
options.SkipXffAppend = true
|
options.SkipXffAppend = true
|
||||||
|
|
|
@ -42,7 +42,7 @@ func (b *Builder) buildOutboundListener(cfg *config.Config) (*envoy_config_liste
|
||||||
func (b *Builder) buildOutboundHTTPConnectionManager() *envoy_config_listener_v3.Filter {
|
func (b *Builder) buildOutboundHTTPConnectionManager() *envoy_config_listener_v3.Filter {
|
||||||
rc := b.buildOutboundRouteConfiguration()
|
rc := b.buildOutboundRouteConfiguration()
|
||||||
|
|
||||||
return HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
return b.HTTPConnectionManagerFilter(&envoy_http_connection_manager.HttpConnectionManager{
|
||||||
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
CodecType: envoy_http_connection_manager.HttpConnectionManager_AUTO,
|
||||||
StatPrefix: "grpc_egress",
|
StatPrefix: "grpc_egress",
|
||||||
// limit request first byte to last byte time
|
// limit request first byte to last byte time
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_buildOutboundRoutes(t *testing.T) {
|
func Test_buildOutboundRoutes(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", nil, nil)
|
b := New("local-grpc", "local-http", "local-metrics", nil, nil, true)
|
||||||
routes := b.buildOutboundRoutes()
|
routes := b.buildOutboundRoutes()
|
||||||
testutil.AssertProtoJSONEqual(t, `[
|
testutil.AssertProtoJSONEqual(t, `[
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BuildRouteConfigurations builds the route configurations for the RDS service.
|
// BuildRouteConfigurations builds the route configurations for the RDS service.
|
||||||
|
|
|
@ -32,7 +32,7 @@ func TestBuilder_buildMainRouteConfiguration(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
b := New("grpc", "http", "metrics", filemgr.NewManager(), nil)
|
b := New("grpc", "http", "metrics", filemgr.NewManager(), nil, true)
|
||||||
routeConfiguration, err := b.buildMainRouteConfiguration(ctx, cfg)
|
routeConfiguration, err := b.buildMainRouteConfiguration(ctx, cfg)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testutil.AssertProtoJSONEqual(t, `{
|
testutil.AssertProtoJSONEqual(t, `{
|
||||||
|
|
|
@ -113,9 +113,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"http2ProtocolOptions": {
|
|
||||||
"allowConnect": true
|
|
||||||
},
|
|
||||||
"localReplyConfig": {
|
"localReplyConfig": {
|
||||||
"mappers": [
|
"mappers": [
|
||||||
{
|
{
|
||||||
|
@ -234,10 +231,6 @@
|
||||||
"addressPrefix": "127.0.0.1",
|
"addressPrefix": "127.0.0.1",
|
||||||
"prefixLen": 32
|
"prefixLen": 32
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"addressPrefix": "::1",
|
|
||||||
"prefixLen": 128
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"addressPrefix": "10.0.0.0",
|
"addressPrefix": "10.0.0.0",
|
||||||
"prefixLen": 8
|
"prefixLen": 8
|
||||||
|
@ -250,6 +243,10 @@
|
||||||
"addressPrefix": "172.16.0.0",
|
"addressPrefix": "172.16.0.0",
|
||||||
"prefixLen": 12
|
"prefixLen": 12
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"addressPrefix": "::1",
|
||||||
|
"prefixLen": 128
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"addressPrefix": "fd00::",
|
"addressPrefix": "fd00::",
|
||||||
"prefixLen": 8
|
"prefixLen": 8
|
||||||
|
|
|
@ -61,10 +61,6 @@
|
||||||
"addressPrefix": "127.0.0.1",
|
"addressPrefix": "127.0.0.1",
|
||||||
"prefixLen": 32
|
"prefixLen": 32
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"addressPrefix": "::1",
|
|
||||||
"prefixLen": 128
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"addressPrefix": "10.0.0.0",
|
"addressPrefix": "10.0.0.0",
|
||||||
"prefixLen": 8
|
"prefixLen": 8
|
||||||
|
@ -77,6 +73,10 @@
|
||||||
"addressPrefix": "172.16.0.0",
|
"addressPrefix": "172.16.0.0",
|
||||||
"prefixLen": 12
|
"prefixLen": 12
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"addressPrefix": "::1",
|
||||||
|
"prefixLen": 128
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"addressPrefix": "fd00::",
|
"addressPrefix": "fd00::",
|
||||||
"prefixLen": 8
|
"prefixLen": 8
|
||||||
|
|
|
@ -82,7 +82,7 @@ func TestValidateCertificate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_buildDownstreamTLSContext(t *testing.T) {
|
func Test_buildDownstreamTLSContext(t *testing.T) {
|
||||||
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil)
|
b := New("local-grpc", "local-http", "local-metrics", filemgr.NewManager(), nil, true)
|
||||||
|
|
||||||
cacheDir, _ := os.UserCacheDir()
|
cacheDir, _ := os.UserCacheDir()
|
||||||
clientCAFileName := filepath.Join(cacheDir, "pomerium", "envoy", "files", "client-ca-4e4c564e5a36544a4a33385a.pem")
|
clientCAFileName := filepath.Join(cacheDir, "pomerium", "envoy", "files", "client-ca-4e4c564e5a36544a4a33385a.pem")
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
extensions_uuidx "github.com/pomerium/envoy-custom/api/extensions/request_id/uuidx"
|
extensions_uuidx "github.com/pomerium/envoy-custom/api/extensions/request_id/uuidx"
|
||||||
extensions_pomerium_otel "github.com/pomerium/envoy-custom/api/extensions/tracers/pomerium_otel"
|
extensions_pomerium_otel "github.com/pomerium/envoy-custom/api/extensions/tracers/pomerium_otel"
|
||||||
"github.com/pomerium/pomerium/config/otelconfig"
|
"github.com/pomerium/pomerium/config/otelconfig"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/middleware"
|
"github.com/pomerium/pomerium/internal/middleware"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry"
|
"github.com/pomerium/pomerium/internal/telemetry"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||||
|
metrics_const "github.com/pomerium/pomerium/pkg/metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -96,12 +97,17 @@ func (mgr *MetricsManager) updateServer(ctx context.Context, cfg *Config) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var labels map[string]string
|
||||||
|
if cfg.Options.IsRuntimeFlagSet(RuntimeFlagAddExtraMetricsLabels) {
|
||||||
|
labels = getCommonLabels(mgr.installationID)
|
||||||
|
}
|
||||||
|
|
||||||
mgr.endpoints = append(cfg.MetricsScrapeEndpoints,
|
mgr.endpoints = append(cfg.MetricsScrapeEndpoints,
|
||||||
MetricsScrapeEndpoint{
|
MetricsScrapeEndpoint{
|
||||||
Name: "envoy",
|
Name: "envoy",
|
||||||
URL: url.URL{Scheme: "http", Host: cfg.Options.MetricsAddr, Path: "/metrics/envoy"},
|
URL: url.URL{Scheme: "http", Host: cfg.Options.MetricsAddr, Path: "/metrics/envoy"},
|
||||||
})
|
})
|
||||||
handler, err := metrics.PrometheusHandler(toInternalEndpoints(mgr.endpoints), mgr.installationID, defaultMetricsTimeout)
|
handler, err := metrics.PrometheusHandler(toInternalEndpoints(mgr.endpoints), defaultMetricsTimeout, labels)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Ctx(ctx).Error().Err(err).Msg("metrics: failed to create prometheus handler")
|
log.Ctx(ctx).Error().Err(err).Msg("metrics: failed to create prometheus handler")
|
||||||
return
|
return
|
||||||
|
@ -128,3 +134,17 @@ func toInternalEndpoints(src []MetricsScrapeEndpoint) []metrics.ScrapeEndpoint {
|
||||||
}
|
}
|
||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCommonLabels(installationID string) map[string]string {
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
hostname = "__none__"
|
||||||
|
}
|
||||||
|
m := map[string]string{
|
||||||
|
metrics_const.HostnameLabel: hostname,
|
||||||
|
}
|
||||||
|
if installationID != "" {
|
||||||
|
m[metrics_const.InstallationIDLabel] = installationID
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
|
@ -196,6 +196,12 @@ type Options struct {
|
||||||
// List of JWT claims to insert as x-pomerium-claim-* headers on proxied requests
|
// List of JWT claims to insert as x-pomerium-claim-* headers on proxied requests
|
||||||
JWTClaimsHeaders JWTClaimHeaders `mapstructure:"jwt_claims_headers" yaml:"jwt_claims_headers,omitempty"`
|
JWTClaimsHeaders JWTClaimHeaders `mapstructure:"jwt_claims_headers" yaml:"jwt_claims_headers,omitempty"`
|
||||||
|
|
||||||
|
// JWTIssuerFormat controls the default format of the 'iss' claim in JWTs passed to upstream services.
|
||||||
|
// Possible values:
|
||||||
|
// - "hostOnly" (default): Issuer strings will be the hostname of the route, with no scheme or trailing slash.
|
||||||
|
// - "uri": Issuer strings will be a complete URI, including the scheme and ending with a trailing slash.
|
||||||
|
JWTIssuerFormat JWTIssuerFormat `mapstructure:"jwt_issuer_format" yaml:"jwt_issuer_format,omitempty"`
|
||||||
|
|
||||||
// BearerTokenFormat indicates how authorization bearer tokens are interepreted. Possible values:
|
// BearerTokenFormat indicates how authorization bearer tokens are interepreted. Possible values:
|
||||||
// - "default": Only Bearer tokens prefixed with Pomerium- will be interpreted by Pomerium.
|
// - "default": Only Bearer tokens prefixed with Pomerium- will be interpreted by Pomerium.
|
||||||
// - "idp_access_token": The Bearer token will be interpreted as an IdP access token.
|
// - "idp_access_token": The Bearer token will be interpreted as an IdP access token.
|
||||||
|
@ -761,6 +767,10 @@ func (o *Options) Validate() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !o.JWTIssuerFormat.Valid() {
|
||||||
|
return fmt.Errorf("config: unsupported jwt_issuer_format value %q", o.JWTIssuerFormat)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1499,8 +1509,6 @@ func (o *Options) ApplySettings(ctx context.Context, certsIndex *cryptutil.Certi
|
||||||
if settings.IdpAccessTokenAllowedAudiences != nil {
|
if settings.IdpAccessTokenAllowedAudiences != nil {
|
||||||
values := slices.Clone(settings.IdpAccessTokenAllowedAudiences.Values)
|
values := slices.Clone(settings.IdpAccessTokenAllowedAudiences.Values)
|
||||||
o.IDPAccessTokenAllowedAudiences = &values
|
o.IDPAccessTokenAllowedAudiences = &values
|
||||||
} else {
|
|
||||||
o.IDPAccessTokenAllowedAudiences = nil
|
|
||||||
}
|
}
|
||||||
setSlice(&o.AuthorizeURLStrings, settings.AuthorizeServiceUrls)
|
setSlice(&o.AuthorizeURLStrings, settings.AuthorizeServiceUrls)
|
||||||
set(&o.AuthorizeInternalURLString, settings.AuthorizeInternalServiceUrl)
|
set(&o.AuthorizeInternalURLString, settings.AuthorizeInternalServiceUrl)
|
||||||
|
@ -1510,10 +1518,13 @@ func (o *Options) ApplySettings(ctx context.Context, certsIndex *cryptutil.Certi
|
||||||
set(&o.SigningKey, settings.SigningKey)
|
set(&o.SigningKey, settings.SigningKey)
|
||||||
setMap(&o.SetResponseHeaders, settings.SetResponseHeaders)
|
setMap(&o.SetResponseHeaders, settings.SetResponseHeaders)
|
||||||
setMap(&o.JWTClaimsHeaders, settings.JwtClaimsHeaders)
|
setMap(&o.JWTClaimsHeaders, settings.JwtClaimsHeaders)
|
||||||
o.BearerTokenFormat = BearerTokenFormatFromPB(settings.BearerTokenFormat)
|
setOptional(&o.BearerTokenFormat, BearerTokenFormatFromPB(settings.BearerTokenFormat))
|
||||||
if len(settings.JwtGroupsFilter) > 0 {
|
if len(settings.JwtGroupsFilter) > 0 {
|
||||||
o.JWTGroupsFilter = NewJWTGroupsFilter(settings.JwtGroupsFilter)
|
o.JWTGroupsFilter = NewJWTGroupsFilter(settings.JwtGroupsFilter)
|
||||||
}
|
}
|
||||||
|
if f := JWTIssuerFormatFromPB(settings.JwtIssuerFormat); f != JWTIssuerFormatUnset {
|
||||||
|
o.JWTIssuerFormat = f
|
||||||
|
}
|
||||||
setDuration(&o.DefaultUpstreamTimeout, settings.DefaultUpstreamTimeout)
|
setDuration(&o.DefaultUpstreamTimeout, settings.DefaultUpstreamTimeout)
|
||||||
set(&o.MetricsAddr, settings.MetricsAddress)
|
set(&o.MetricsAddr, settings.MetricsAddress)
|
||||||
set(&o.MetricsBasicAuth, settings.MetricsBasicAuth)
|
set(&o.MetricsBasicAuth, settings.MetricsBasicAuth)
|
||||||
|
@ -1624,6 +1635,7 @@ func (o *Options) ToProto() *config.Config {
|
||||||
settings.JwtClaimsHeaders = o.JWTClaimsHeaders
|
settings.JwtClaimsHeaders = o.JWTClaimsHeaders
|
||||||
settings.BearerTokenFormat = o.BearerTokenFormat.ToPB()
|
settings.BearerTokenFormat = o.BearerTokenFormat.ToPB()
|
||||||
settings.JwtGroupsFilter = o.JWTGroupsFilter.ToSlice()
|
settings.JwtGroupsFilter = o.JWTGroupsFilter.ToSlice()
|
||||||
|
settings.JwtIssuerFormat = o.JWTIssuerFormat.ToPB()
|
||||||
copyOptionalDuration(&settings.DefaultUpstreamTimeout, o.DefaultUpstreamTimeout)
|
copyOptionalDuration(&settings.DefaultUpstreamTimeout, o.DefaultUpstreamTimeout)
|
||||||
copySrcToOptionalDest(&settings.MetricsAddress, &o.MetricsAddr)
|
copySrcToOptionalDest(&settings.MetricsAddress, &o.MetricsAddr)
|
||||||
copySrcToOptionalDest(&settings.MetricsBasicAuth, &o.MetricsBasicAuth)
|
copySrcToOptionalDest(&settings.MetricsBasicAuth, &o.MetricsBasicAuth)
|
||||||
|
|
|
@ -924,6 +924,8 @@ func TestOptions_GetAllRouteableHTTPHosts(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOptions_ApplySettings(t *testing.T) {
|
func TestOptions_ApplySettings(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
ctx, clearTimeout := context.WithTimeout(context.Background(), time.Second)
|
ctx, clearTimeout := context.WithTimeout(context.Background(), time.Second)
|
||||||
defer clearTimeout()
|
defer clearTimeout()
|
||||||
|
|
||||||
|
@ -989,6 +991,48 @@ func TestOptions_ApplySettings(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.Equal(t, NewJWTGroupsFilter([]string{"quux", "zulu"}), options.JWTGroupsFilter)
|
assert.Equal(t, NewJWTGroupsFilter([]string{"quux", "zulu"}), options.JWTGroupsFilter)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("jwt_issuer_format", func(t *testing.T) {
|
||||||
|
options := NewDefaultOptions()
|
||||||
|
assert.Equal(t, JWTIssuerFormatUnset, options.JWTIssuerFormat)
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{
|
||||||
|
JwtIssuerFormat: configpb.IssuerFormat_IssuerURI.Enum(),
|
||||||
|
})
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{})
|
||||||
|
assert.Equal(t, JWTIssuerFormatURI, options.JWTIssuerFormat)
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{
|
||||||
|
JwtIssuerFormat: configpb.IssuerFormat_IssuerHostOnly.Enum(),
|
||||||
|
})
|
||||||
|
assert.Equal(t, JWTIssuerFormatHostOnly, options.JWTIssuerFormat)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("bearer_token_format", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
options := NewDefaultOptions()
|
||||||
|
assert.Nil(t, options.BearerTokenFormat)
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{
|
||||||
|
BearerTokenFormat: configpb.BearerTokenFormat_BEARER_TOKEN_FORMAT_DEFAULT.Enum(),
|
||||||
|
})
|
||||||
|
assert.Equal(t, ptr(BearerTokenFormatDefault), options.BearerTokenFormat)
|
||||||
|
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{})
|
||||||
|
assert.Equal(t, ptr(BearerTokenFormatDefault), options.BearerTokenFormat, "should preserve existing bearer token format")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("idp_access_token_allowed_audiences", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
options := NewDefaultOptions()
|
||||||
|
assert.Nil(t, options.IDPAccessTokenAllowedAudiences)
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{
|
||||||
|
IdpAccessTokenAllowedAudiences: &configpb.Settings_StringList{Values: []string{"x", "y", "z"}},
|
||||||
|
})
|
||||||
|
assert.Equal(t, ptr([]string{"x", "y", "z"}), options.IDPAccessTokenAllowedAudiences)
|
||||||
|
options.ApplySettings(ctx, nil, &configpb.Settings{})
|
||||||
|
assert.Equal(t, ptr([]string{"x", "y", "z"}), options.IDPAccessTokenAllowedAudiences,
|
||||||
|
"should preserve idp access token allowed audiences")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOptions_GetSetResponseHeaders(t *testing.T) {
|
func TestOptions_GetSetResponseHeaders(t *testing.T) {
|
||||||
|
@ -1748,3 +1792,7 @@ func must[T any](t T, err error) T {
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ptr[T any](v T) *T {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
|
@ -167,7 +167,7 @@ type Policy struct {
|
||||||
// Possible values:
|
// Possible values:
|
||||||
// - "hostOnly" (default): Issuer strings will be the hostname of the route, with no scheme or trailing slash.
|
// - "hostOnly" (default): Issuer strings will be the hostname of the route, with no scheme or trailing slash.
|
||||||
// - "uri": Issuer strings will be a complete URI, including the scheme and ending with a trailing slash.
|
// - "uri": Issuer strings will be a complete URI, including the scheme and ending with a trailing slash.
|
||||||
JWTIssuerFormat string `mapstructure:"jwt_issuer_format" yaml:"jwt_issuer_format,omitempty"`
|
JWTIssuerFormat JWTIssuerFormat `mapstructure:"jwt_issuer_format" yaml:"jwt_issuer_format,omitempty"`
|
||||||
// BearerTokenFormat indicates how authorization bearer tokens are interepreted. Possible values:
|
// BearerTokenFormat indicates how authorization bearer tokens are interepreted. Possible values:
|
||||||
// - "default": Only Bearer tokens prefixed with Pomerium- will be interpreted by Pomerium
|
// - "default": Only Bearer tokens prefixed with Pomerium- will be interpreted by Pomerium
|
||||||
// - "idp_access_token": The Bearer token will be interpreted as an IdP access token.
|
// - "idp_access_token": The Bearer token will be interpreted as an IdP access token.
|
||||||
|
@ -309,6 +309,7 @@ func NewPolicyFromProto(pb *configpb.Route) (*Policy, error) {
|
||||||
IDPClientID: pb.GetIdpClientId(),
|
IDPClientID: pb.GetIdpClientId(),
|
||||||
IDPClientSecret: pb.GetIdpClientSecret(),
|
IDPClientSecret: pb.GetIdpClientSecret(),
|
||||||
JWTGroupsFilter: NewJWTGroupsFilter(pb.JwtGroupsFilter),
|
JWTGroupsFilter: NewJWTGroupsFilter(pb.JwtGroupsFilter),
|
||||||
|
JWTIssuerFormat: JWTIssuerFormatFromPB(pb.JwtIssuerFormat),
|
||||||
KubernetesServiceAccountToken: pb.GetKubernetesServiceAccountToken(),
|
KubernetesServiceAccountToken: pb.GetKubernetesServiceAccountToken(),
|
||||||
KubernetesServiceAccountTokenFile: pb.GetKubernetesServiceAccountTokenFile(),
|
KubernetesServiceAccountTokenFile: pb.GetKubernetesServiceAccountTokenFile(),
|
||||||
LogoURL: pb.GetLogoUrl(),
|
LogoURL: pb.GetLogoUrl(),
|
||||||
|
@ -388,13 +389,6 @@ func NewPolicyFromProto(pb *configpb.Route) (*Policy, error) {
|
||||||
p.EnvoyOpts.Name = pb.Name
|
p.EnvoyOpts.Name = pb.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
switch pb.GetJwtIssuerFormat() {
|
|
||||||
case configpb.IssuerFormat_IssuerHostOnly:
|
|
||||||
p.JWTIssuerFormat = "hostOnly"
|
|
||||||
case configpb.IssuerFormat_IssuerURI:
|
|
||||||
p.JWTIssuerFormat = "uri"
|
|
||||||
}
|
|
||||||
|
|
||||||
p.BearerTokenFormat = BearerTokenFormatFromPB(pb.BearerTokenFormat)
|
p.BearerTokenFormat = BearerTokenFormatFromPB(pb.BearerTokenFormat)
|
||||||
|
|
||||||
for _, rwh := range pb.RewriteResponseHeaders {
|
for _, rwh := range pb.RewriteResponseHeaders {
|
||||||
|
@ -468,6 +462,7 @@ func (p *Policy) ToProto() (*configpb.Route, error) {
|
||||||
Id: p.ID,
|
Id: p.ID,
|
||||||
IdleTimeout: idleTimeout,
|
IdleTimeout: idleTimeout,
|
||||||
JwtGroupsFilter: p.JWTGroupsFilter.ToSlice(),
|
JwtGroupsFilter: p.JWTGroupsFilter.ToSlice(),
|
||||||
|
JwtIssuerFormat: p.JWTIssuerFormat.ToPB(),
|
||||||
KubernetesServiceAccountToken: p.KubernetesServiceAccountToken,
|
KubernetesServiceAccountToken: p.KubernetesServiceAccountToken,
|
||||||
KubernetesServiceAccountTokenFile: p.KubernetesServiceAccountTokenFile,
|
KubernetesServiceAccountTokenFile: p.KubernetesServiceAccountTokenFile,
|
||||||
LogoUrl: p.LogoURL,
|
LogoUrl: p.LogoURL,
|
||||||
|
@ -555,13 +550,6 @@ func (p *Policy) ToProto() (*configpb.Route, error) {
|
||||||
pb.LoadBalancingWeights = weights
|
pb.LoadBalancingWeights = weights
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.JWTIssuerFormat {
|
|
||||||
case "", "hostOnly":
|
|
||||||
pb.JwtIssuerFormat = configpb.IssuerFormat_IssuerHostOnly
|
|
||||||
case "uri":
|
|
||||||
pb.JwtIssuerFormat = configpb.IssuerFormat_IssuerURI
|
|
||||||
}
|
|
||||||
|
|
||||||
pb.BearerTokenFormat = p.BearerTokenFormat.ToPB()
|
pb.BearerTokenFormat = p.BearerTokenFormat.ToPB()
|
||||||
|
|
||||||
for _, rwh := range p.RewriteResponseHeaders {
|
for _, rwh := range p.RewriteResponseHeaders {
|
||||||
|
@ -698,6 +686,10 @@ func (p *Policy) Validate() error {
|
||||||
p.compiledRegex, _ = regexp.Compile(rawRE)
|
p.compiledRegex, _ = regexp.Compile(rawRE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !p.JWTIssuerFormat.Valid() {
|
||||||
|
return fmt.Errorf("config: unsupported jwt_issuer_format value %q", p.JWTIssuerFormat)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -292,6 +292,22 @@ func TestPolicy_FromToPb(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, p.Redirect.HTTPSRedirect, policyFromProto.Redirect.HTTPSRedirect)
|
assert.Equal(t, p.Redirect.HTTPSRedirect, policyFromProto.Redirect.HTTPSRedirect)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("JWT issuer format", func(t *testing.T) {
|
||||||
|
for f := range knownJWTIssuerFormats {
|
||||||
|
p := &Policy{
|
||||||
|
From: "https://pomerium.io",
|
||||||
|
To: mustParseWeightedURLs(t, "http://localhost"),
|
||||||
|
JWTIssuerFormat: f,
|
||||||
|
}
|
||||||
|
pbPolicy, err := p.ToProto()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
policyFromPb, err := NewPolicyFromProto(pbPolicy)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, f, policyFromPb.JWTIssuerFormat)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPolicy_Matches(t *testing.T) {
|
func TestPolicy_Matches(t *testing.T) {
|
||||||
|
|
|
@ -25,6 +25,9 @@ var (
|
||||||
// is deprecated pending removal in a future release, but this flag allows a temporary
|
// is deprecated pending removal in a future release, but this flag allows a temporary
|
||||||
// opt-out from the deprecation.
|
// opt-out from the deprecation.
|
||||||
RuntimeFlagPomeriumJWTEndpoint = runtimeFlag("pomerium_jwt_endpoint", false)
|
RuntimeFlagPomeriumJWTEndpoint = runtimeFlag("pomerium_jwt_endpoint", false)
|
||||||
|
|
||||||
|
// RuntimeFlagAddExtraMetricsLabels enables adding extra labels to metrics (host and installation id)
|
||||||
|
RuntimeFlagAddExtraMetricsLabels = runtimeFlag("add_extra_metrics_labels", true)
|
||||||
)
|
)
|
||||||
|
|
||||||
// RuntimeFlag is a runtime flag that can flip on/off certain features
|
// RuntimeFlag is a runtime flag that can flip on/off certain features
|
||||||
|
|
|
@ -202,7 +202,7 @@ func (c *incomingIDPTokenSessionCreator) createSessionAccessToken(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error verifying access token: %w", err)
|
return nil, fmt.Errorf("error verifying access token: %w", err)
|
||||||
} else if !res.Valid {
|
} else if !res.Valid {
|
||||||
return nil, fmt.Errorf("invalid access token")
|
return nil, fmt.Errorf("%w: invalid access token", sessions.ErrInvalidSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
s = c.newSessionFromIDPClaims(cfg, sessionID, res.Claims)
|
s = c.newSessionFromIDPClaims(cfg, sessionID, res.Claims)
|
||||||
|
@ -265,7 +265,7 @@ func (c *incomingIDPTokenSessionCreator) createSessionForIdentityToken(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error verifying identity token: %w", err)
|
return nil, fmt.Errorf("error verifying identity token: %w", err)
|
||||||
} else if !res.Valid {
|
} else if !res.Valid {
|
||||||
return nil, fmt.Errorf("invalid identity token")
|
return nil, fmt.Errorf("%w: invalid identity token", sessions.ErrInvalidSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
s = c.newSessionFromIDPClaims(cfg, sessionID, res.Claims)
|
s = c.newSessionFromIDPClaims(cfg, sessionID, res.Claims)
|
||||||
|
@ -405,22 +405,8 @@ func (cfg *Config) GetIncomingIDPAccessTokenForPolicy(policy *Policy, r *http.Re
|
||||||
bearerTokenFormat = *policy.BearerTokenFormat
|
bearerTokenFormat = *policy.BearerTokenFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
if token := r.Header.Get(httputil.HeaderPomeriumIDPAccessToken); token != "" {
|
|
||||||
return token, true
|
|
||||||
}
|
|
||||||
|
|
||||||
if auth := r.Header.Get(httputil.HeaderAuthorization); auth != "" {
|
if auth := r.Header.Get(httputil.HeaderAuthorization); auth != "" {
|
||||||
prefix := httputil.AuthorizationTypePomeriumIDPAccessToken + " "
|
prefix := "Bearer "
|
||||||
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) {
|
|
||||||
return auth[len(prefix):], true
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix = "Bearer " + httputil.AuthorizationTypePomeriumIDPAccessToken + "-"
|
|
||||||
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) {
|
|
||||||
return auth[len(prefix):], true
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix = "Bearer "
|
|
||||||
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) &&
|
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) &&
|
||||||
bearerTokenFormat == BearerTokenFormatIDPAccessToken {
|
bearerTokenFormat == BearerTokenFormatIDPAccessToken {
|
||||||
return auth[len(prefix):], true
|
return auth[len(prefix):], true
|
||||||
|
@ -440,22 +426,8 @@ func (cfg *Config) GetIncomingIDPIdentityTokenForPolicy(policy *Policy, r *http.
|
||||||
bearerTokenFormat = *policy.BearerTokenFormat
|
bearerTokenFormat = *policy.BearerTokenFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
if token := r.Header.Get(httputil.HeaderPomeriumIDPIdentityToken); token != "" {
|
|
||||||
return token, true
|
|
||||||
}
|
|
||||||
|
|
||||||
if auth := r.Header.Get(httputil.HeaderAuthorization); auth != "" {
|
if auth := r.Header.Get(httputil.HeaderAuthorization); auth != "" {
|
||||||
prefix := httputil.AuthorizationTypePomeriumIDPIdentityToken + " "
|
prefix := "Bearer "
|
||||||
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) {
|
|
||||||
return auth[len(prefix):], true
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix = "Bearer " + httputil.AuthorizationTypePomeriumIDPIdentityToken + "-"
|
|
||||||
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) {
|
|
||||||
return auth[len(prefix):], true
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix = "Bearer "
|
|
||||||
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) &&
|
if strings.HasPrefix(strings.ToLower(auth), strings.ToLower(prefix)) &&
|
||||||
bearerTokenFormat == BearerTokenFormatIDPIdentityToken {
|
bearerTokenFormat == BearerTokenFormatIDPIdentityToken {
|
||||||
return auth[len(prefix):], true
|
return auth[len(prefix):], true
|
||||||
|
|
|
@ -206,24 +206,6 @@ func TestGetIncomingIDPAccessTokenForPolicy(t *testing.T) {
|
||||||
name: "empty headers",
|
name: "empty headers",
|
||||||
expectedOK: false,
|
expectedOK: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "custom header",
|
|
||||||
headers: http.Header{"X-Pomerium-Idp-Access-Token": {"access token via custom header"}},
|
|
||||||
expectedOK: true,
|
|
||||||
expectedToken: "access token via custom header",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom authorization",
|
|
||||||
headers: http.Header{"Authorization": {"Pomerium-Idp-Access-Token access token via custom authorization"}},
|
|
||||||
expectedOK: true,
|
|
||||||
expectedToken: "access token via custom authorization",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom bearer",
|
|
||||||
headers: http.Header{"Authorization": {"Bearer Pomerium-Idp-Access-Token-access token via custom bearer"}},
|
|
||||||
expectedOK: true,
|
|
||||||
expectedToken: "access token via custom bearer",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "bearer disabled",
|
name: "bearer disabled",
|
||||||
headers: http.Header{"Authorization": {"Bearer access token via bearer"}},
|
headers: http.Header{"Authorization": {"Bearer access token via bearer"}},
|
||||||
|
@ -289,24 +271,6 @@ func TestGetIncomingIDPIdentityTokenForPolicy(t *testing.T) {
|
||||||
name: "empty headers",
|
name: "empty headers",
|
||||||
expectedOK: false,
|
expectedOK: false,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "custom header",
|
|
||||||
headers: http.Header{"X-Pomerium-Idp-Identity-Token": {"identity token via custom header"}},
|
|
||||||
expectedOK: true,
|
|
||||||
expectedToken: "identity token via custom header",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom authorization",
|
|
||||||
headers: http.Header{"Authorization": {"Pomerium-Idp-Identity-Token identity token via custom authorization"}},
|
|
||||||
expectedOK: true,
|
|
||||||
expectedToken: "identity token via custom authorization",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "custom bearer",
|
|
||||||
headers: http.Header{"Authorization": {"Bearer Pomerium-Idp-Identity-Token-identity token via custom bearer"}},
|
|
||||||
expectedOK: true,
|
|
||||||
expectedToken: "identity token via custom bearer",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "bearer disabled",
|
name: "bearer disabled",
|
||||||
headers: http.Header{"Authorization": {"Bearer identity token via bearer"}},
|
headers: http.Header{"Authorization": {"Bearer identity token via bearer"}},
|
||||||
|
@ -496,12 +460,14 @@ func TestIncomingIDPTokenSessionCreator_CreateSession(t *testing.T) {
|
||||||
cfg.Options.AuthenticateURLString = srv.URL
|
cfg.Options.AuthenticateURLString = srv.URL
|
||||||
cfg.Options.ClientSecret = "CLIENT_SECRET_1"
|
cfg.Options.ClientSecret = "CLIENT_SECRET_1"
|
||||||
cfg.Options.ClientID = "CLIENT_ID_1"
|
cfg.Options.ClientID = "CLIENT_ID_1"
|
||||||
|
bearerTokenFormatIDPAccessToken := BearerTokenFormatIDPAccessToken
|
||||||
|
cfg.Options.BearerTokenFormat = &bearerTokenFormatIDPAccessToken
|
||||||
route := &Policy{}
|
route := &Policy{}
|
||||||
route.IDPClientSecret = "CLIENT_SECRET_2"
|
route.IDPClientSecret = "CLIENT_SECRET_2"
|
||||||
route.IDPClientID = "CLIENT_ID_2"
|
route.IDPClientID = "CLIENT_ID_2"
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://www.example.com", nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://www.example.com", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
req.Header.Set(httputil.HeaderPomeriumIDPAccessToken, "ACCESS_TOKEN")
|
req.Header.Set("Authorization", "Bearer ACCESS_TOKEN")
|
||||||
c := NewIncomingIDPTokenSessionCreator(
|
c := NewIncomingIDPTokenSessionCreator(
|
||||||
func(_ context.Context, _, _ string) (*databroker.Record, error) {
|
func(_ context.Context, _, _ string) (*databroker.Record, error) {
|
||||||
return nil, storage.ErrNotFound
|
return nil, storage.ErrNotFound
|
||||||
|
@ -537,12 +503,14 @@ func TestIncomingIDPTokenSessionCreator_CreateSession(t *testing.T) {
|
||||||
cfg.Options.AuthenticateURLString = srv.URL
|
cfg.Options.AuthenticateURLString = srv.URL
|
||||||
cfg.Options.ClientSecret = "CLIENT_SECRET_1"
|
cfg.Options.ClientSecret = "CLIENT_SECRET_1"
|
||||||
cfg.Options.ClientID = "CLIENT_ID_1"
|
cfg.Options.ClientID = "CLIENT_ID_1"
|
||||||
|
bearerTokenFormatIDPIdentityToken := BearerTokenFormatIDPIdentityToken
|
||||||
|
cfg.Options.BearerTokenFormat = &bearerTokenFormatIDPIdentityToken
|
||||||
route := &Policy{}
|
route := &Policy{}
|
||||||
route.IDPClientSecret = "CLIENT_SECRET_2"
|
route.IDPClientSecret = "CLIENT_SECRET_2"
|
||||||
route.IDPClientID = "CLIENT_ID_2"
|
route.IDPClientID = "CLIENT_ID_2"
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://www.example.com", nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://www.example.com", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
req.Header.Set(httputil.HeaderPomeriumIDPIdentityToken, "IDENTITY_TOKEN")
|
req.Header.Set("Authorization", "Bearer IDENTITY_TOKEN")
|
||||||
c := NewIncomingIDPTokenSessionCreator(
|
c := NewIncomingIDPTokenSessionCreator(
|
||||||
func(_ context.Context, _, _ string) (*databroker.Record, error) {
|
func(_ context.Context, _, _ string) (*databroker.Record, error) {
|
||||||
return nil, storage.ErrNotFound
|
return nil, storage.ErrNotFound
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/atomicutil"
|
"github.com/pomerium/pomerium/internal/atomicutil"
|
||||||
"github.com/pomerium/pomerium/internal/events"
|
"github.com/pomerium/pomerium/internal/events"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/version"
|
"github.com/pomerium/pomerium/internal/version"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/envoy/files"
|
"github.com/pomerium/pomerium/pkg/envoy/files"
|
||||||
|
@ -29,6 +28,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/pkg/identity"
|
"github.com/pomerium/pomerium/pkg/identity"
|
||||||
"github.com/pomerium/pomerium/pkg/identity/legacymanager"
|
"github.com/pomerium/pomerium/pkg/identity/legacymanager"
|
||||||
"github.com/pomerium/pomerium/pkg/identity/manager"
|
"github.com/pomerium/pomerium/pkg/identity/manager"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
14
go.mod
14
go.mod
|
@ -88,15 +88,15 @@ require (
|
||||||
go.uber.org/automaxprocs v1.6.0
|
go.uber.org/automaxprocs v1.6.0
|
||||||
go.uber.org/mock v0.5.0
|
go.uber.org/mock v0.5.0
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
golang.org/x/crypto v0.33.0
|
golang.org/x/crypto v0.36.0
|
||||||
golang.org/x/net v0.35.0
|
golang.org/x/net v0.37.0
|
||||||
golang.org/x/oauth2 v0.27.0
|
golang.org/x/oauth2 v0.27.0
|
||||||
golang.org/x/sync v0.11.0
|
golang.org/x/sync v0.12.0
|
||||||
golang.org/x/sys v0.30.0
|
golang.org/x/sys v0.31.0
|
||||||
golang.org/x/time v0.10.0
|
golang.org/x/time v0.10.0
|
||||||
google.golang.org/api v0.223.0
|
google.golang.org/api v0.223.0
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250219182151-9fdb1cabc7b2
|
||||||
google.golang.org/grpc v1.70.0
|
google.golang.org/grpc v1.71.0
|
||||||
google.golang.org/protobuf v1.36.5
|
google.golang.org/protobuf v1.36.5
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
sigs.k8s.io/yaml v1.4.0
|
sigs.k8s.io/yaml v1.4.0
|
||||||
|
@ -230,7 +230,7 @@ require (
|
||||||
github.com/zeebo/assert v1.3.1 // indirect
|
github.com/zeebo/assert v1.3.1 // indirect
|
||||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 // indirect
|
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/aws v1.34.0 // indirect
|
go.opentelemetry.io/contrib/propagators/aws v1.34.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/b3 v1.34.0 // indirect
|
go.opentelemetry.io/contrib/propagators/b3 v1.34.0 // indirect
|
||||||
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0 // indirect
|
go.opentelemetry.io/contrib/propagators/jaeger v1.34.0 // indirect
|
||||||
|
@ -239,7 +239,7 @@ require (
|
||||||
go.uber.org/zap/exp v0.3.0 // indirect
|
go.uber.org/zap/exp v0.3.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
|
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
|
||||||
golang.org/x/mod v0.20.0 // indirect
|
golang.org/x/mod v0.20.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
golang.org/x/tools v0.24.0 // indirect
|
golang.org/x/tools v0.24.0 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
|
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||||
|
|
32
go.sum
32
go.sum
|
@ -690,8 +690,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0 h1:P78qWqkLSShicHmAzfECaTgvslqHxblNE9j62Ws1NK8=
|
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=
|
||||||
go.opentelemetry.io/contrib/detectors/gcp v1.32.0/go.mod h1:TVqo0Sda4Cv8gCIixd7LuLwW4EylumVWfhjZJjDD4DU=
|
go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
||||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
||||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
||||||
|
@ -750,8 +750,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
@ -827,8 +827,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
@ -851,8 +851,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -912,15 +912,15 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -931,8 +931,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
@ -1061,8 +1061,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
|
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||||
google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
|
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
|
|
|
@ -14,10 +14,10 @@ import (
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/types/known/structpb"
|
"google.golang.org/protobuf/types/known/structpb"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/grpc"
|
"github.com/pomerium/pomerium/pkg/grpc"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||||
"github.com/pomerium/pomerium/pkg/identity"
|
"github.com/pomerium/pomerium/pkg/identity"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// timeNow is time.Now but pulled out as a variable for tests.
|
// timeNow is time.Now but pulled out as a variable for tests.
|
||||||
|
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/sessions"
|
"github.com/pomerium/pomerium/internal/sessions"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc"
|
"github.com/pomerium/pomerium/pkg/grpc"
|
||||||
|
@ -33,6 +32,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/pkg/grpcutil"
|
"github.com/pomerium/pomerium/pkg/grpcutil"
|
||||||
"github.com/pomerium/pomerium/pkg/identity"
|
"github.com/pomerium/pomerium/pkg/identity"
|
||||||
"github.com/pomerium/pomerium/pkg/identity/manager"
|
"github.com/pomerium/pomerium/pkg/identity/manager"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Stateful implements the stateful authentication flow. In this flow, the
|
// Stateful implements the stateful authentication flow. In this flow, the
|
||||||
|
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/sessions"
|
"github.com/pomerium/pomerium/internal/sessions"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc"
|
"github.com/pomerium/pomerium/pkg/grpc"
|
||||||
|
@ -31,6 +30,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/user"
|
"github.com/pomerium/pomerium/pkg/grpc/user"
|
||||||
"github.com/pomerium/pomerium/pkg/hpke"
|
"github.com/pomerium/pomerium/pkg/hpke"
|
||||||
"github.com/pomerium/pomerium/pkg/identity"
|
"github.com/pomerium/pomerium/pkg/identity"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
|
|
|
@ -17,10 +17,10 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/middleware"
|
"github.com/pomerium/pomerium/internal/middleware"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry"
|
"github.com/pomerium/pomerium/internal/telemetry"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
hpke_handlers "github.com/pomerium/pomerium/pkg/hpke/handlers"
|
hpke_handlers "github.com/pomerium/pomerium/pkg/hpke/handlers"
|
||||||
"github.com/pomerium/pomerium/pkg/telemetry/requestid"
|
"github.com/pomerium/pomerium/pkg/telemetry/requestid"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (srv *Server) addHTTPMiddleware(ctx context.Context, root *mux.Router, _ *config.Config) {
|
func (srv *Server) addHTTPMiddleware(ctx context.Context, root *mux.Router, _ *config.Config) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||||
coltracepb "go.opentelemetry.io/proto/otlp/collector/trace/v1"
|
coltracepb "go.opentelemetry.io/proto/otlp/collector/trace/v1"
|
||||||
|
"golang.org/x/net/nettest"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/health/grpc_health_v1"
|
"google.golang.org/grpc/health/grpc_health_v1"
|
||||||
|
@ -27,7 +28,6 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/events"
|
"github.com/pomerium/pomerium/internal/events"
|
||||||
"github.com/pomerium/pomerium/internal/httputil/reproxy"
|
"github.com/pomerium/pomerium/internal/httputil/reproxy"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
"github.com/pomerium/pomerium/internal/version"
|
"github.com/pomerium/pomerium/internal/version"
|
||||||
"github.com/pomerium/pomerium/pkg/envoy/files"
|
"github.com/pomerium/pomerium/pkg/envoy/files"
|
||||||
|
@ -35,6 +35,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/pkg/grpcutil"
|
"github.com/pomerium/pomerium/pkg/grpcutil"
|
||||||
"github.com/pomerium/pomerium/pkg/httputil"
|
"github.com/pomerium/pomerium/pkg/httputil"
|
||||||
"github.com/pomerium/pomerium/pkg/telemetry/requestid"
|
"github.com/pomerium/pomerium/pkg/telemetry/requestid"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -177,6 +178,7 @@ func NewServer(
|
||||||
srv.MetricsListener.Addr().String(),
|
srv.MetricsListener.Addr().String(),
|
||||||
srv.filemgr,
|
srv.filemgr,
|
||||||
srv.reproxy,
|
srv.reproxy,
|
||||||
|
nettest.SupportsIPv6(),
|
||||||
)
|
)
|
||||||
|
|
||||||
res, err := srv.buildDiscoveryResources(ctx)
|
res, err := srv.buildDiscoveryResources(ctx)
|
||||||
|
|
|
@ -15,13 +15,13 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/hashutil"
|
"github.com/pomerium/pomerium/internal/hashutil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc"
|
"github.com/pomerium/pomerium/pkg/grpc"
|
||||||
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||||
"github.com/pomerium/pomerium/pkg/grpcutil"
|
"github.com/pomerium/pomerium/pkg/grpcutil"
|
||||||
"github.com/pomerium/pomerium/pkg/health"
|
"github.com/pomerium/pomerium/pkg/health"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
googlegrpc "google.golang.org/grpc"
|
googlegrpc "google.golang.org/grpc"
|
||||||
|
|
|
@ -17,11 +17,11 @@ import (
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/registry"
|
"github.com/pomerium/pomerium/internal/registry"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
"github.com/pomerium/pomerium/pkg/grpc/databroker"
|
||||||
"github.com/pomerium/pomerium/pkg/storage"
|
"github.com/pomerium/pomerium/pkg/storage"
|
||||||
"github.com/pomerium/pomerium/pkg/storage/inmemory"
|
"github.com/pomerium/pomerium/pkg/storage/inmemory"
|
||||||
"github.com/pomerium/pomerium/pkg/storage/postgres"
|
"github.com/pomerium/pomerium/pkg/storage/postgres"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ const (
|
||||||
// can be used in place of the standard authorization header if that header is being
|
// can be used in place of the standard authorization header if that header is being
|
||||||
// used by upstream applications.
|
// used by upstream applications.
|
||||||
HeaderPomeriumAuthorization = "x-pomerium-authorization"
|
HeaderPomeriumAuthorization = "x-pomerium-authorization"
|
||||||
HeaderPomeriumIDPAccessToken = "x-pomerium-idp-access-token" //nolint: gosec
|
|
||||||
HeaderPomeriumIDPIdentityToken = "x-pomerium-idp-identity-token" //nolint: gosec
|
|
||||||
// HeaderPomeriumResponse is set when pomerium itself creates a response,
|
// HeaderPomeriumResponse is set when pomerium itself creates a response,
|
||||||
// as opposed to the upstream application and can be used to distinguish
|
// as opposed to the upstream application and can be used to distinguish
|
||||||
// between an application error, and a pomerium related error when debugging.
|
// between an application error, and a pomerium related error when debugging.
|
||||||
|
|
|
@ -8,6 +8,9 @@ var (
|
||||||
// ErrNoSessionFound is the error for when no session is found.
|
// ErrNoSessionFound is the error for when no session is found.
|
||||||
ErrNoSessionFound = errors.New("internal/sessions: session is not found")
|
ErrNoSessionFound = errors.New("internal/sessions: session is not found")
|
||||||
|
|
||||||
|
// ErrInvalidSession is the error for when a session is invalid.
|
||||||
|
ErrInvalidSession = errors.New("internal/sessions: invalid session")
|
||||||
|
|
||||||
// ErrMalformed is the error for when a session is found but is malformed.
|
// ErrMalformed is the error for when a session is found but is malformed.
|
||||||
ErrMalformed = errors.New("internal/sessions: session is malformed")
|
ErrMalformed = errors.New("internal/sessions: session is malformed")
|
||||||
|
|
||||||
|
|
115
internal/telemetry/metrics/bench_test.go
Normal file
115
internal/telemetry/metrics/bench_test.go
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
package metrics_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"sort"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pomerium/pomerium/config"
|
||||||
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
|
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
||||||
|
"github.com/pomerium/pomerium/internal/testenv/upstreams"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestScrapeMetricsEndpoint(t *testing.T) {
|
||||||
|
t.Skip("this test is for profiling purposes only")
|
||||||
|
|
||||||
|
env := testenv.New(t, testenv.WithTraceDebugFlags(testenv.StandardTraceDebugFlags))
|
||||||
|
upstream := upstreams.HTTP(nil)
|
||||||
|
upstream.Handle("/test", func(w http.ResponseWriter, _ *http.Request) {
|
||||||
|
w.Write([]byte("OK"))
|
||||||
|
})
|
||||||
|
|
||||||
|
routes := []testenv.Route{}
|
||||||
|
for i := range 10 {
|
||||||
|
routes = append(routes, upstream.Route().
|
||||||
|
From(env.SubdomainURL(fmt.Sprintf("test-%d", i))).
|
||||||
|
Policy(func(p *config.Policy) { p.AllowPublicUnauthenticatedAccess = true }))
|
||||||
|
}
|
||||||
|
env.AddUpstream(upstream)
|
||||||
|
env.Start()
|
||||||
|
snippets.WaitStartupComplete(env)
|
||||||
|
|
||||||
|
for _, r := range routes {
|
||||||
|
resp, err := upstream.Get(r, upstreams.Path("/test"))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
data, err := io.ReadAll(resp.Body)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
resp.Body.Close()
|
||||||
|
assert.Equal(t, "OK", string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
metricsURL := fmt.Sprintf("http://localhost:%d/metrics", env.Ports().Metrics.Value())
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Timeout: 10 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
|
var durations []time.Duration
|
||||||
|
var totalBytes int64
|
||||||
|
var errors int
|
||||||
|
|
||||||
|
pct := 0
|
||||||
|
niter := 200
|
||||||
|
for i := 0; i < niter; i++ {
|
||||||
|
pct = i * 100 / niter
|
||||||
|
if pct%10 == 0 {
|
||||||
|
t.Log(pct, "%")
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
resp, err := client.Get(metricsURL)
|
||||||
|
elapsed := time.Since(start)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("Request %d failed: %v", i, err)
|
||||||
|
errors++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
nb, err := io.Copy(io.Discard, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
resp.Body.Close()
|
||||||
|
errors++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
durations = append(durations, elapsed)
|
||||||
|
totalBytes += nb
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(durations) > 0 {
|
||||||
|
sort.Slice(durations, func(i, j int) bool {
|
||||||
|
return durations[i] < durations[j]
|
||||||
|
})
|
||||||
|
|
||||||
|
var total time.Duration
|
||||||
|
for _, d := range durations {
|
||||||
|
total += d
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("Metrics scraping statistics:")
|
||||||
|
t.Logf(" Successful requests: %d", len(durations))
|
||||||
|
t.Logf(" Failed requests: %d", errors)
|
||||||
|
t.Logf(" Total bytes: %d", totalBytes)
|
||||||
|
t.Logf(" Avg bytes per request: %.2f", float64(totalBytes)/float64(len(durations)))
|
||||||
|
t.Logf(" Min: %v", durations[0])
|
||||||
|
t.Logf(" Max: %v", durations[len(durations)-1])
|
||||||
|
t.Logf(" Avg: %v", total/time.Duration(len(durations)))
|
||||||
|
t.Logf(" p50: %v", durations[len(durations)*50/100])
|
||||||
|
t.Logf(" p90: %v", durations[len(durations)*90/100])
|
||||||
|
t.Logf(" p95: %v", durations[len(durations)*95/100])
|
||||||
|
t.Logf(" p99: %v", durations[len(durations)*99/100])
|
||||||
|
} else {
|
||||||
|
t.Logf("No successful requests made")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("metrics endpoint: %s", metricsURL)
|
||||||
|
|
||||||
|
env.Stop()
|
||||||
|
}
|
|
@ -240,11 +240,11 @@ var (
|
||||||
Measure: identityManagerLastSessionRefreshSuccess,
|
Measure: identityManagerLastSessionRefreshSuccess,
|
||||||
Aggregation: view.Count(),
|
Aggregation: view.Count(),
|
||||||
}
|
}
|
||||||
// IdentityManagerLastSessionRefreshErrorView contains user refresh errors counter
|
// IdentityManagerLastSessionRefreshErrorView contains session refresh errors counter
|
||||||
IdentityManagerLastSessionRefreshErrorView = &view.View{
|
IdentityManagerLastSessionRefreshErrorView = &view.View{
|
||||||
Name: identityManagerLastUserRefreshError.Name(),
|
Name: identityManagerLastSessionRefreshError.Name(),
|
||||||
Description: identityManagerLastUserRefreshError.Description(),
|
Description: identityManagerLastSessionRefreshError.Description(),
|
||||||
Measure: identityManagerLastUserRefreshError,
|
Measure: identityManagerLastSessionRefreshError,
|
||||||
Aggregation: view.Count(),
|
Aggregation: view.Count(),
|
||||||
}
|
}
|
||||||
// IdentityManagerLastSessionRefreshSuccessTimestampView contains successful session refresh counter
|
// IdentityManagerLastSessionRefreshSuccessTimestampView contains successful session refresh counter
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -22,7 +21,6 @@ import (
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/prometheus"
|
"github.com/pomerium/pomerium/internal/telemetry/prometheus"
|
||||||
"github.com/pomerium/pomerium/pkg/metrics"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnvoyMetricsPath is the path on the metrics listener that retrieves envoy metrics.
|
// EnvoyMetricsPath is the path on the metrics listener that retrieves envoy metrics.
|
||||||
|
@ -44,7 +42,7 @@ func (e *ScrapeEndpoint) String() string {
|
||||||
|
|
||||||
// PrometheusHandler creates an exporter that exports stats to Prometheus
|
// PrometheusHandler creates an exporter that exports stats to Prometheus
|
||||||
// and returns a handler suitable for exporting metrics.
|
// and returns a handler suitable for exporting metrics.
|
||||||
func PrometheusHandler(endpoints []ScrapeEndpoint, installationID string, timeout time.Duration) (http.Handler, error) {
|
func PrometheusHandler(endpoints []ScrapeEndpoint, timeout time.Duration, labels map[string]string) (http.Handler, error) {
|
||||||
exporter, err := getGlobalExporter()
|
exporter, err := getGlobalExporter()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -52,7 +50,7 @@ func PrometheusHandler(endpoints []ScrapeEndpoint, installationID string, timeou
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
mux.Handle("/metrics", newProxyMetricsHandler(exporter, endpoints, installationID, timeout))
|
mux.Handle("/metrics", newProxyMetricsHandler(exporter, endpoints, timeout, labels))
|
||||||
return mux, nil
|
return mux, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,12 +94,16 @@ func registerDefaultViews() error {
|
||||||
|
|
||||||
// newProxyMetricsHandler creates a subrequest to the envoy control plane for metrics and
|
// newProxyMetricsHandler creates a subrequest to the envoy control plane for metrics and
|
||||||
// combines them with internal envoy-provided
|
// combines them with internal envoy-provided
|
||||||
func newProxyMetricsHandler(exporter *ocprom.Exporter, endpoints []ScrapeEndpoint, installationID string, timeout time.Duration) http.HandlerFunc {
|
func newProxyMetricsHandler(
|
||||||
|
exporter *ocprom.Exporter,
|
||||||
|
endpoints []ScrapeEndpoint,
|
||||||
|
timeout time.Duration,
|
||||||
|
labels map[string]string,
|
||||||
|
) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), timeout)
|
ctx, cancel := context.WithTimeout(r.Context(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
labels := getCommonLabels(installationID)
|
|
||||||
if err := writeMetricsMux(ctx, w, append(
|
if err := writeMetricsMux(ctx, w, append(
|
||||||
scrapeEndpoints(endpoints, labels),
|
scrapeEndpoints(endpoints, labels),
|
||||||
ocExport("pomerium", exporter, r, labels)),
|
ocExport("pomerium", exporter, r, labels)),
|
||||||
|
@ -156,7 +158,7 @@ func writeMetricsResult(w io.Writer, res promProducerResult) error {
|
||||||
return fmt.Errorf("fetch: %w", res.err)
|
return fmt.Errorf("fetch: %w", res.err)
|
||||||
}
|
}
|
||||||
return errors.Join(
|
return errors.Join(
|
||||||
prometheus.Export(w, prometheus.AddLabels(prometheus.NewMetricFamilyStream(res.src), res.labels)),
|
prometheus.RelabelTextStream(w, res.src, res.labels),
|
||||||
res.src.Close(),
|
res.src.Close(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -229,17 +231,3 @@ func scrapeEndpoint(endpoint ScrapeEndpoint, extra map[string]string) promProduc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCommonLabels(installationID string) map[string]string {
|
|
||||||
hostname, err := os.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
hostname = "__none__"
|
|
||||||
}
|
|
||||||
m := map[string]string{
|
|
||||||
metrics.HostnameLabel: hostname,
|
|
||||||
}
|
|
||||||
if installationID != "" {
|
|
||||||
m[metrics.InstallationIDLabel] = installationID
|
|
||||||
}
|
|
||||||
return m
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ envoy_server_initialization_time_ms_bucket{le="1000"} 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMetrics(t *testing.T, envoyURL *url.URL, header http.Header) []byte {
|
func getMetrics(t *testing.T, envoyURL *url.URL, header http.Header) []byte {
|
||||||
h, err := PrometheusHandler([]ScrapeEndpoint{{Name: "envoy", URL: *envoyURL}}, "test_installation_id", time.Second*20)
|
h, err := PrometheusHandler([]ScrapeEndpoint{{Name: "envoy", URL: *envoyURL}}, time.Second*20, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
103
internal/telemetry/prometheus/relabel_text_stream.go
Normal file
103
internal/telemetry/prometheus/relabel_text_stream.go
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
package prometheus
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"maps"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func writeMulti(dst io.Writer, b ...[]byte) error {
|
||||||
|
for _, buf := range b {
|
||||||
|
if _, err := dst.Write(buf); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RelabelTextStream relabels a prometheus text stream by adding additional labels to each metric.
|
||||||
|
func RelabelTextStream(dst io.Writer, src io.Reader, addLabels map[string]string) error {
|
||||||
|
if len(addLabels) == 0 {
|
||||||
|
_, err := io.Copy(dst, src)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var labelsBuilder strings.Builder
|
||||||
|
for _, k := range slices.Sorted(maps.Keys(addLabels)) {
|
||||||
|
v := addLabels[k]
|
||||||
|
if labelsBuilder.Len() > 0 {
|
||||||
|
labelsBuilder.WriteByte(',')
|
||||||
|
}
|
||||||
|
labelsBuilder.WriteString(k)
|
||||||
|
labelsBuilder.WriteString("=\"")
|
||||||
|
labelsBuilder.WriteString(v)
|
||||||
|
labelsBuilder.WriteString("\"")
|
||||||
|
}
|
||||||
|
addedLabels := []byte(labelsBuilder.String())
|
||||||
|
|
||||||
|
r := bufio.NewReader(src)
|
||||||
|
|
||||||
|
for {
|
||||||
|
line, err := r.ReadSlice('\n')
|
||||||
|
if errors.Is(err, io.EOF) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(line) == 0 || line[0] == '#' {
|
||||||
|
if _, err := dst.Write(line); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
spaceIdx := bytes.IndexByte(line, ' ')
|
||||||
|
if spaceIdx == -1 {
|
||||||
|
if _, err := dst.Write(line); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
metricWithLabels := line[:spaceIdx]
|
||||||
|
value := line[spaceIdx:]
|
||||||
|
|
||||||
|
openBraceIdx := bytes.IndexByte(metricWithLabels, '{')
|
||||||
|
if openBraceIdx == -1 { // no labels
|
||||||
|
if err := writeMulti(dst, metricWithLabels, []byte("{"), addedLabels, []byte("}"), value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
metricName := metricWithLabels[:openBraceIdx]
|
||||||
|
|
||||||
|
closeBraceIdx := bytes.LastIndexByte(metricWithLabels, '}')
|
||||||
|
if closeBraceIdx == -1 || closeBraceIdx <= openBraceIdx {
|
||||||
|
if _, err := dst.Write(line); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
existingLabels := metricWithLabels[openBraceIdx+1 : closeBraceIdx]
|
||||||
|
|
||||||
|
if len(existingLabels) > 0 {
|
||||||
|
if err := writeMulti(dst, metricName, []byte("{"), existingLabels, []byte(","), addedLabels, []byte("}"), value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := writeMulti(dst, metricName, []byte("{"), addedLabels, []byte("}"), value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
141
internal/telemetry/prometheus/relabel_text_stream_test.go
Normal file
141
internal/telemetry/prometheus/relabel_text_stream_test.go
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
package prometheus_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pomerium/pomerium/internal/telemetry/prometheus"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RepeatingReader repeats reading from the beginning after EOF for a specified number of times
|
||||||
|
type RepeatingReader struct {
|
||||||
|
reader *bytes.Reader
|
||||||
|
resets int
|
||||||
|
maxResets int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRepeatingReader creates a new reader that will reset up to maxResets times
|
||||||
|
func NewRepeatingReader(data []byte, maxResets int) *RepeatingReader {
|
||||||
|
return &RepeatingReader{
|
||||||
|
reader: bytes.NewReader(data),
|
||||||
|
resets: 0,
|
||||||
|
maxResets: maxResets,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read implements io.Reader
|
||||||
|
func (r *RepeatingReader) Read(p []byte) (n int, err error) {
|
||||||
|
n, err = r.reader.Read(p)
|
||||||
|
if err == io.EOF && r.resets < r.maxResets {
|
||||||
|
r.reader.Seek(0, io.SeekStart)
|
||||||
|
r.resets++
|
||||||
|
return r.Read(p)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkRelabelTestStream(b *testing.B) {
|
||||||
|
addLabels := map[string]string{"instance": "localhost:9090", "installation_id": "12345-67890-12345-67890"}
|
||||||
|
src := []byte(`
|
||||||
|
# TYPE envoy_cluster_upstream_cx_total counter
|
||||||
|
envoy_cluster_upstream_cx_total{service="pomerium-proxy",envoy_cluster_name="route-1",installation_id="aecd6525-9eaa-448d-93d9-6363c04b1ccb",hostname="pomerium-proxy-55589cc5f-fjhsb"} 2
|
||||||
|
envoy_cluster_upstream_cx_total{service="pomerium-proxy",envoy_cluster_name="route-2",installation_id="aecd6525-9eaa-448d-93d9-6363c04b1ccb",hostname="pomerium-proxy-55589cc5f-fjhsb"} 3
|
||||||
|
`)
|
||||||
|
|
||||||
|
b.Run("RelabelTextStream", func(b *testing.B) {
|
||||||
|
inputReader := NewRepeatingReader(src, b.N)
|
||||||
|
err := prometheus.RelabelTextStream(io.Discard, inputReader, addLabels)
|
||||||
|
require.NoError(b, err)
|
||||||
|
})
|
||||||
|
b.Run("Previous", func(b *testing.B) {
|
||||||
|
inputReader := NewRepeatingReader(src, b.N)
|
||||||
|
err := prometheus.Export(io.Discard, prometheus.AddLabels(prometheus.NewMetricFamilyStream(inputReader), addLabels))
|
||||||
|
require.NoError(b, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRelabelTextStream(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
addLabels map[string]string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty input",
|
||||||
|
input: "",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no labels to add",
|
||||||
|
input: "metric 42\n",
|
||||||
|
addLabels: map[string]string{},
|
||||||
|
expected: "metric 42\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "comment lines",
|
||||||
|
input: "# HELP metric_name Help text\n# TYPE metric_name counter\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "# HELP metric_name Help text\n# TYPE metric_name counter\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "metric without labels",
|
||||||
|
input: "http_requests_total 42\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "http_requests_total{instance=\"localhost:9090\"} 42\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "metric with existing labels",
|
||||||
|
input: "http_requests_total{method=\"GET\"} 42\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "http_requests_total{method=\"GET\",instance=\"localhost:9090\"} 42\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple labels to add",
|
||||||
|
input: "http_requests_total 42\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090", "job": "prometheus"},
|
||||||
|
expected: "http_requests_total{instance=\"localhost:9090\",job=\"prometheus\"} 42\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "malformed metric (no space)",
|
||||||
|
input: "invalid_metric\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "invalid_metric\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "malformed metric (no closing brace)",
|
||||||
|
input: "invalid_metric{label=\"value\" 42\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "invalid_metric{label=\"value\" 42\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty labels",
|
||||||
|
input: "http_requests_total{} 42\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "http_requests_total{instance=\"localhost:9090\"} 42\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple metrics",
|
||||||
|
input: "metric1 10\nmetric2{label=\"value\"} 20\n# COMMENT\nmetric3 30\n",
|
||||||
|
addLabels: map[string]string{"instance": "localhost:9090"},
|
||||||
|
expected: "metric1{instance=\"localhost:9090\"} 10\nmetric2{label=\"value\",instance=\"localhost:9090\"} 20\n# COMMENT\nmetric3{instance=\"localhost:9090\"} 30\n",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
inputReader := strings.NewReader(tc.input)
|
||||||
|
outputBuffer := &bytes.Buffer{}
|
||||||
|
|
||||||
|
err := prometheus.RelabelTextStream(outputBuffer, inputReader, tc.addLabels)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
actual := outputBuffer.String()
|
||||||
|
require.Equal(t, tc.expected, actual)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,7 +36,6 @@ import (
|
||||||
"github.com/pomerium/pomerium/config/envoyconfig/filemgr"
|
"github.com/pomerium/pomerium/config/envoyconfig/filemgr"
|
||||||
databroker_service "github.com/pomerium/pomerium/databroker"
|
databroker_service "github.com/pomerium/pomerium/databroker"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv/envutil"
|
"github.com/pomerium/pomerium/internal/testenv/envutil"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/values"
|
"github.com/pomerium/pomerium/internal/testenv/values"
|
||||||
"github.com/pomerium/pomerium/pkg/cmd/pomerium"
|
"github.com/pomerium/pomerium/pkg/cmd/pomerium"
|
||||||
|
@ -47,6 +46,7 @@ import (
|
||||||
"github.com/pomerium/pomerium/pkg/identity/manager"
|
"github.com/pomerium/pomerium/pkg/identity/manager"
|
||||||
"github.com/pomerium/pomerium/pkg/netutil"
|
"github.com/pomerium/pomerium/pkg/netutil"
|
||||||
"github.com/pomerium/pomerium/pkg/slices"
|
"github.com/pomerium/pomerium/pkg/slices"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/rs/zerolog"
|
"github.com/rs/zerolog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
|
@ -21,12 +21,12 @@ import (
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv"
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/scenarios"
|
"github.com/pomerium/pomerium/internal/testenv/scenarios"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/upstreams"
|
"github.com/pomerium/pomerium/internal/testenv/upstreams"
|
||||||
. "github.com/pomerium/pomerium/internal/testutil/tracetest" //nolint:revive
|
. "github.com/pomerium/pomerium/internal/testutil/tracetest" //nolint:revive
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
var allServices = []string{
|
var allServices = []string{
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv"
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
"github.com/pomerium/pomerium/pkg/grpcutil"
|
"github.com/pomerium/pomerium/pkg/grpcutil"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/connectivity"
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv"
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/values"
|
"github.com/pomerium/pomerium/internal/testenv/values"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
"go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
|
|
@ -21,10 +21,10 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pomerium/pomerium/integration/forms"
|
"github.com/pomerium/pomerium/integration/forms"
|
||||||
"github.com/pomerium/pomerium/internal/retry"
|
"github.com/pomerium/pomerium/internal/retry"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv"
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/values"
|
"github.com/pomerium/pomerium/internal/testenv/values"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/minio/minio-go/v7"
|
"github.com/minio/minio-go/v7"
|
||||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/testcontainers/testcontainers-go"
|
"github.com/testcontainers/testcontainers-go"
|
||||||
"github.com/testcontainers/testcontainers-go/wait"
|
"github.com/testcontainers/testcontainers-go/wait"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/testcontainers/testcontainers-go"
|
"github.com/testcontainers/testcontainers-go"
|
||||||
"github.com/testcontainers/testcontainers-go/wait"
|
"github.com/testcontainers/testcontainers-go/wait"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
"unique"
|
"unique"
|
||||||
|
|
||||||
gocmp "github.com/google/go-cmp/cmp"
|
gocmp "github.com/google/go-cmp/cmp"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
|
|
|
@ -48,6 +48,7 @@ func New(
|
||||||
func (c *client) getGRPCConn(ctx context.Context) (*grpc.ClientConn, error) {
|
func (c *client) getGRPCConn(ctx context.Context) (*grpc.ClientConn, error) {
|
||||||
opts := append(
|
opts := append(
|
||||||
c.config.GetDialOptions(),
|
c.config.GetDialOptions(),
|
||||||
|
grpc.WithAuthority(c.config.GetAuthority()),
|
||||||
grpc.WithPerRPCCredentials(c),
|
grpc.WithPerRPCCredentials(c),
|
||||||
grpc.WithDefaultCallOptions(
|
grpc.WithDefaultCallOptions(
|
||||||
grpc.UseCompressor("gzip"),
|
grpc.UseCompressor("gzip"),
|
||||||
|
@ -60,7 +61,7 @@ func (c *client) getGRPCConn(ctx context.Context) (*grpc.ClientConn, error) {
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
conn, err := grpc.DialContext(ctx, c.config.GetConnectionURI(), opts...)
|
conn, err := grpc.NewClient(c.config.GetConnectionURI(), opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error dialing grpc server: %w", err)
|
return nil, fmt.Errorf("error dialing grpc server: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -92,7 +93,7 @@ func (c *client) logConnectionState(ctx context.Context, conn *grpc.ClientConn)
|
||||||
_ = conn.WaitForStateChange(ctx, state)
|
_ = conn.WaitForStateChange(ctx, state)
|
||||||
state = conn.GetState()
|
state = conn.GetState()
|
||||||
log.Ctx(ctx).Debug().
|
log.Ctx(ctx).Debug().
|
||||||
Str("endpoint", c.config.connectionURI).
|
Str("endpoint", c.config.GetConnectionURI()).
|
||||||
Str("state", state.String()).
|
Str("state", state.String()).
|
||||||
Msg("grpc connection state")
|
Msg("grpc connection state")
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,8 @@ import (
|
||||||
|
|
||||||
// config is the configuration for the gRPC client
|
// config is the configuration for the gRPC client
|
||||||
type config struct {
|
type config struct {
|
||||||
connectionURI string
|
// authority is a host:port string that will be used as the :authority pseudo-header
|
||||||
|
authority string
|
||||||
// requireTLS is whether TLS should be used or cleartext
|
// requireTLS is whether TLS should be used or cleartext
|
||||||
requireTLS bool
|
requireTLS bool
|
||||||
// opts are additional options to pass to the gRPC client
|
// opts are additional options to pass to the gRPC client
|
||||||
|
@ -41,9 +42,14 @@ func getConfig(
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAuthority returns the authority to use in the :authority pseudo-header
|
||||||
|
func (c *config) GetAuthority() string {
|
||||||
|
return c.authority
|
||||||
|
}
|
||||||
|
|
||||||
// GetConnectionURI returns connection string conforming to https://github.com/grpc/grpc/blob/master/doc/naming.md
|
// GetConnectionURI returns connection string conforming to https://github.com/grpc/grpc/blob/master/doc/naming.md
|
||||||
func (c *config) GetConnectionURI() string {
|
func (c *config) GetConnectionURI() string {
|
||||||
return c.connectionURI
|
return "dns:" + c.authority
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDialTimeout returns the timeout for the dial operation
|
// GetDialTimeout returns the timeout for the dial operation
|
||||||
|
@ -101,7 +107,7 @@ func (c *config) parseEndpoint(endpoint string) error {
|
||||||
return fmt.Errorf("unsupported url scheme: %s", u.Scheme)
|
return fmt.Errorf("unsupported url scheme: %s", u.Scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.connectionURI = fmt.Sprintf("dns:%s:%s", host, port)
|
c.authority = host + ":" + port
|
||||||
c.requireTLS = requireTLS
|
c.requireTLS = requireTLS
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -23,11 +23,11 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/events"
|
"github.com/pomerium/pomerium/internal/events"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/registry"
|
"github.com/pomerium/pomerium/internal/registry"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/version"
|
"github.com/pomerium/pomerium/internal/version"
|
||||||
derivecert_config "github.com/pomerium/pomerium/pkg/derivecert/config"
|
derivecert_config "github.com/pomerium/pomerium/pkg/derivecert/config"
|
||||||
"github.com/pomerium/pomerium/pkg/envoy"
|
"github.com/pomerium/pomerium/pkg/envoy"
|
||||||
"github.com/pomerium/pomerium/pkg/envoy/files"
|
"github.com/pomerium/pomerium/pkg/envoy/files"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/pomerium/pomerium/proxy"
|
"github.com/pomerium/pomerium/proxy"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
||||||
)
|
)
|
||||||
|
|
|
@ -713,7 +713,7 @@ func TestSharedResourceMonitor(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBootstrapConfig(t *testing.T) {
|
func TestBootstrapConfig(t *testing.T) {
|
||||||
b := envoyconfig.New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil)
|
b := envoyconfig.New("localhost:1111", "localhost:2222", "localhost:3333", filemgr.NewManager(), nil, true)
|
||||||
testEnvoyPid := 99
|
testEnvoyPid := 99
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
monitor, err := NewSharedResourceMonitor(context.Background(), config.NewStaticSource(nil), tempDir, WithCgroupDriver(&cgroupV2Driver{
|
monitor, err := NewSharedResourceMonitor(context.Background(), config.NewStaticSource(nil), tempDir, WithCgroupDriver(&cgroupV2Driver{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -123,7 +123,7 @@ message Route {
|
||||||
string kubernetes_service_account_token = 26;
|
string kubernetes_service_account_token = 26;
|
||||||
string kubernetes_service_account_token_file = 64;
|
string kubernetes_service_account_token_file = 64;
|
||||||
bool enable_google_cloud_serverless_authentication = 42;
|
bool enable_google_cloud_serverless_authentication = 42;
|
||||||
IssuerFormat jwt_issuer_format = 65;
|
optional IssuerFormat jwt_issuer_format = 65;
|
||||||
repeated string jwt_groups_filter = 66;
|
repeated string jwt_groups_filter = 66;
|
||||||
optional BearerTokenFormat bearer_token_format = 70;
|
optional BearerTokenFormat bearer_token_format = 70;
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ message Policy {
|
||||||
string remediation = 9;
|
string remediation = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next ID: 139.
|
// Next ID: 140.
|
||||||
message Settings {
|
message Settings {
|
||||||
message Certificate {
|
message Certificate {
|
||||||
bytes cert_bytes = 3;
|
bytes cert_bytes = 3;
|
||||||
|
@ -214,6 +214,7 @@ message Settings {
|
||||||
map<string, string> set_response_headers = 69;
|
map<string, string> set_response_headers = 69;
|
||||||
// repeated string jwt_claims_headers = 37;
|
// repeated string jwt_claims_headers = 37;
|
||||||
map<string, string> jwt_claims_headers = 63;
|
map<string, string> jwt_claims_headers = 63;
|
||||||
|
optional IssuerFormat jwt_issuer_format = 139;
|
||||||
repeated string jwt_groups_filter = 119;
|
repeated string jwt_groups_filter = 119;
|
||||||
optional BearerTokenFormat bearer_token_format = 138;
|
optional BearerTokenFormat bearer_token_format = 138;
|
||||||
optional google.protobuf.Duration default_upstream_timeout = 39;
|
optional google.protobuf.Duration default_upstream_timeout = 39;
|
||||||
|
|
|
@ -16,11 +16,11 @@ import (
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
"github.com/pomerium/pomerium/internal/version"
|
"github.com/pomerium/pomerium/internal/version"
|
||||||
"github.com/pomerium/pomerium/pkg/identity/identity"
|
"github.com/pomerium/pomerium/pkg/identity/identity"
|
||||||
"github.com/pomerium/pomerium/pkg/identity/oauth"
|
"github.com/pomerium/pomerium/pkg/identity/oauth"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Name identifies the generic OpenID Connect provider.
|
// Name identifies the generic OpenID Connect provider.
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,13 +13,13 @@ import (
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/testenv"
|
"github.com/pomerium/pomerium/internal/testenv"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/scenarios"
|
"github.com/pomerium/pomerium/internal/testenv/scenarios"
|
||||||
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
"github.com/pomerium/pomerium/internal/testenv/snippets"
|
||||||
. "github.com/pomerium/pomerium/internal/testutil/tracetest" //nolint:revive
|
. "github.com/pomerium/pomerium/internal/testutil/tracetest" //nolint:revive
|
||||||
"github.com/pomerium/pomerium/internal/testutil/tracetest/mock_otlptrace"
|
"github.com/pomerium/pomerium/internal/testutil/tracetest/mock_otlptrace"
|
||||||
"github.com/pomerium/pomerium/internal/version"
|
"github.com/pomerium/pomerium/internal/version"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
. "github.com/pomerium/pomerium/internal/testutil/tracetest" //nolint:revive
|
. "github.com/pomerium/pomerium/internal/testutil/tracetest" //nolint:revive
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
oteltrace "go.opentelemetry.io/otel/trace"
|
oteltrace "go.opentelemetry.io/otel/trace"
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
"go.opentelemetry.io/otel/trace/noop"
|
"go.opentelemetry.io/otel/trace/noop"
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
@ -17,7 +17,6 @@ import (
|
||||||
"github.com/pomerium/datasource/pkg/directory"
|
"github.com/pomerium/datasource/pkg/directory"
|
||||||
"github.com/pomerium/pomerium/config"
|
"github.com/pomerium/pomerium/config"
|
||||||
"github.com/pomerium/pomerium/internal/databroker"
|
"github.com/pomerium/pomerium/internal/databroker"
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
|
||||||
"github.com/pomerium/pomerium/internal/sessions"
|
"github.com/pomerium/pomerium/internal/sessions"
|
||||||
"github.com/pomerium/pomerium/internal/testutil"
|
"github.com/pomerium/pomerium/internal/testutil"
|
||||||
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
configpb "github.com/pomerium/pomerium/pkg/grpc/config"
|
||||||
|
@ -47,7 +46,7 @@ func Test_getUserInfoData(t *testing.T) {
|
||||||
proxy.state.Load().dataBrokerClient = client
|
proxy.state.Load().dataBrokerClient = client
|
||||||
|
|
||||||
r := httptest.NewRequest(http.MethodGet, "/.pomerium/", nil)
|
r := httptest.NewRequest(http.MethodGet, "/.pomerium/", nil)
|
||||||
r.Header.Set(httputil.HeaderPomeriumIDPAccessToken, "ACCESS_TOKEN")
|
r.Header.Set("Authorization", "Bearer ACCESS_TOKEN")
|
||||||
data := proxy.getUserInfoData(r)
|
data := proxy.getUserInfoData(r)
|
||||||
assert.NotNil(t, data.Session)
|
assert.NotNil(t, data.Session)
|
||||||
assert.NotNil(t, data.User)
|
assert.NotNil(t, data.User)
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/handlers"
|
"github.com/pomerium/pomerium/internal/handlers"
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/middleware"
|
"github.com/pomerium/pomerium/internal/middleware"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/internal/urlutil"
|
"github.com/pomerium/pomerium/internal/urlutil"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// registerDashboardHandlers returns the proxy service's ServeMux
|
// registerDashboardHandlers returns the proxy service's ServeMux
|
||||||
|
|
|
@ -19,8 +19,8 @@ import (
|
||||||
"github.com/pomerium/pomerium/internal/httputil"
|
"github.com/pomerium/pomerium/internal/httputil"
|
||||||
"github.com/pomerium/pomerium/internal/log"
|
"github.com/pomerium/pomerium/internal/log"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
|
||||||
"github.com/pomerium/pomerium/pkg/cryptutil"
|
"github.com/pomerium/pomerium/pkg/cryptutil"
|
||||||
|
"github.com/pomerium/pomerium/pkg/telemetry/trace"
|
||||||
"github.com/pomerium/pomerium/proxy/portal"
|
"github.com/pomerium/pomerium/proxy/portal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@ func testOptions(t *testing.T) *config.Options {
|
||||||
opts.Services = config.ServiceAll
|
opts.Services = config.ServiceAll
|
||||||
opts.SharedKey = "80ldlrU2d7w+wVpKNfevk6fmb8otEx6CqOfshj2LwhQ="
|
opts.SharedKey = "80ldlrU2d7w+wVpKNfevk6fmb8otEx6CqOfshj2LwhQ="
|
||||||
opts.CookieSecret = "OromP1gurwGWjQPYb1nNgSxtbVB5NnLzX6z5WOKr0Yw="
|
opts.CookieSecret = "OromP1gurwGWjQPYb1nNgSxtbVB5NnLzX6z5WOKr0Yw="
|
||||||
|
bearerTokenFormatIDPAccessToken := config.BearerTokenFormatIDPAccessToken
|
||||||
|
opts.BearerTokenFormat = &bearerTokenFormatIDPAccessToken
|
||||||
|
|
||||||
hpkePrivateKey, err := opts.GetHPKEPrivateKey()
|
hpkePrivateKey, err := opts.GetHPKEPrivateKey()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue