Skip to content

Commit

Permalink
README, test/e2e: add --allow-legacy-serviceaccount-tokens flag
Browse files Browse the repository at this point in the history
Signed-off-by: kramaranya <kramaranya15@gmail.com>
  • Loading branch information
kramaranya committed Mar 3, 2025
1 parent a9c2ea9 commit a8e9da6
Show file tree
Hide file tree
Showing 27 changed files with 370 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ Delegating authorization flags:
Proxy flags:
--allow-legacy-serviceaccount-tokens If true, allow legacy service account tokens (without an audience). Legacy tokens are less secure and are disabled by default.
--allow-paths strings Comma-separated list of paths against which kube-rbac-proxy pattern-matches the incoming request. If the request doesn't match, kube-rbac-proxy responds with a 404 status code. If omitted, the incoming request path isn't checked. Cannot be used with --ignore-paths.
--auth-header-groups-field-name string The name of the field inside a http(2) request header to tell the upstream server about the user's groups (default "x-remote-groups")
--auth-header-groups-field-separator string The separator string used for concatenating multiple group names in a groups header field's value (default "|")
--auth-header-user-field-name string The name of the field inside a http(2) request header to tell the upstream server about the user's name (default "x-remote-user")
--auth-token-audiences strings Comma-separated list of token audiences to accept. By default a token does not have to have any specific audience. It is recommended to set a specific audience.
--auth-token-audiences strings Comma-separated list of token audiences to accept. Tokens must have at least one audience from this list. Must be set unless --allow-legacy-serviceaccount-tokens is true.
--config-file string Configuration file to configure static and rewrites authorization of the kube-rbac-proxy.
--disable-http2-serving If true, HTTP2 serving will be disabled [default=false]
--ignore-paths strings Comma-separated list of paths against which kube-rbac-proxy pattern-matches the incoming request. If the requst matches, it will proxy the request without performing an authentication or authorization check. Cannot be used with --allow-paths.
Expand Down
2 changes: 1 addition & 1 deletion cmd/kube-rbac-proxy/app/options/proxyoptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (o *ProxyOptions) AddFlags(flagset *pflag.FlagSet) {
flagset.StringVar(&o.UpstreamHeader.GroupsFieldName, "auth-header-groups-field-name", "x-remote-groups", "The name of the field inside a http(2) request header to tell the upstream server about the user's groups")
flagset.StringVar(&o.UpstreamHeader.GroupSeparator, "auth-header-groups-field-separator", "|", "The separator string used for concatenating multiple group names in a groups header field's value")

flagset.StringSliceVar(&o.TokenAudiences, "auth-token-audiences", []string{}, "Comma-separated list of token audiences to accept. Tokens must have at least one audience from this list. If omitted, the token is considered legacy.")
flagset.StringSliceVar(&o.TokenAudiences, "auth-token-audiences", []string{}, "Comma-separated list of token audiences to accept. Tokens must have at least one audience from this list. Must be set unless --allow-legacy-serviceaccount-tokens is true.")

// legacy tokens are disabled by default.
flagset.BoolVar(&o.AllowLegacyServiceAccountTokens, "allow-legacy-serviceaccount-tokens", false, "If true, allow legacy service account tokens (without an audience). Legacy tokens are less secure and are disabled by default.")
Expand Down
72 changes: 69 additions & 3 deletions cmd/kube-rbac-proxy/app/options/proxyoptions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ limitations under the License.
package options

import (
"github.com/brancz/kube-rbac-proxy/pkg/authn/identityheaders"
"os"
"path/filepath"
"reflect"
"testing"

"github.com/google/go-cmp/cmp"

"github.com/brancz/kube-rbac-proxy/pkg/authn/identityheaders"
authz "github.com/brancz/kube-rbac-proxy/pkg/authorization"
"github.com/brancz/kube-rbac-proxy/pkg/authorization/rewrite"
"github.com/brancz/kube-rbac-proxy/pkg/authorization/static"
Expand Down Expand Up @@ -144,14 +144,37 @@ func TestProxyOptions_Validate(t *testing.T) {
DisableHTTP2Serving bool
}

userKey := "User"
groupKey := "Group"
const (
userKey = "User"
groupKey = "Group"
)

tests := []struct {
name string
fields fields
wantErr bool
}{
{
name: "valid config with client cert, key, config, port, and token audience",
fields: fields{
Upstream: "http://127.0.0.1",
UpstreamForceH2C: true,
UpstreamCAFile: "ca.crt",
UpstreamClientCertFile: "client.crt",
UpstreamClientKeyFile: "client.key",
AuthzConfigFileName: "authz.yaml",
AllowPaths: []string{"/path1", "/path2"},
ProxyEndpointsPort: 8081,
TokenAudiences: []string{"kube-apiserver"},
AllowLegacyServiceAccountTokens: false,
DisableHTTP2Serving: true,
UpstreamHeader: &identityheaders.AuthnHeaderConfig{
UserFieldName: userKey,
GroupsFieldName: groupKey,
},
},
wantErr: false,
},
{
name: "valid config with explicit token audience",
fields: fields{
Expand Down Expand Up @@ -191,6 +214,49 @@ func TestProxyOptions_Validate(t *testing.T) {
},
wantErr: false,
},
{
name: "invalid combination (both AllowPaths and IgnorePaths set)",
fields: fields{
Upstream: "http://127.0.0.1",
AllowPaths: []string{"/path1"},
IgnorePaths: []string{"/path2"},
TokenAudiences: []string{"kube-apiserver"},
AllowLegacyServiceAccountTokens: false,
UpstreamHeader: &identityheaders.AuthnHeaderConfig{
UserFieldName: userKey,
GroupsFieldName: groupKey,
},
},
wantErr: true,
},
{
name: "invalid AllowPaths",
fields: fields{
Upstream: "http://127.0.0.1",
AllowPaths: []string{"[path"},
TokenAudiences: []string{"kube-apiserver"},
AllowLegacyServiceAccountTokens: false,
UpstreamHeader: &identityheaders.AuthnHeaderConfig{
UserFieldName: userKey,
GroupsFieldName: groupKey,
},
},
wantErr: true,
},
{
name: "invalid IgnorePaths",
fields: fields{
Upstream: "http://127.0.0.1",
IgnorePaths: []string{"path\\"},
TokenAudiences: []string{"kube-apiserver"},
AllowLegacyServiceAccountTokens: false,
UpstreamHeader: &identityheaders.AuthnHeaderConfig{
UserFieldName: userKey,
GroupsFieldName: groupKey,
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions test/e2e/allowpaths/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ spec:
- "--proxy-endpoints-port=8643"
- "--upstream=http://127.0.0.1:8081/"
- "--allow-paths=/metrics,/api/v1/label/*"
- "--allow-legacy-serviceaccount-tokens=true"
- "--authentication-skip-lookup"
- "--v=10"
ports:
Expand Down
124 changes: 124 additions & 0 deletions test/e2e/basics.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,3 +519,127 @@ func testIgnorePaths(client kubernetes.Interface) kubetest.TestSuite {
}.Run(t)
}
}

func testLegacyTokenFlag(client kubernetes.Interface) kubetest.TestSuite {
return func(t *testing.T) {
legacyCommand := `curl --connect-timeout 5 -v -s -k --fail -H "Authorization: Bearer $(cat /var/run/secrets/tokens/requestedtoken)" https://kube-rbac-proxy.default.svc.cluster.local:8443/metrics`
command := `curl --connect-timeout 5 -v -s -k --fail -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kube-rbac-proxy.default.svc.cluster.local:8443/metrics`

kubetest.Scenario{
Name: "LegacyAllowedAudienceSet",
Description: `
As a client with --allow-legacy-serviceaccount-tokens=true and a valid audience,
I succeed with my request
`,

Given: kubetest.Actions(
kubetest.CreatedManifests(
client,
"legacy/clusterRole.yaml",
"legacy/clusterRoleBinding.yaml",
"legacy/deployment-allowed.yaml",
"legacy/service.yaml",
"legacy/serviceAccount.yaml",
"legacy/clusterRole-client.yaml",
"legacy/clusterRoleBinding-client.yaml",
),
),
When: kubetest.Actions(
kubetest.PodsAreReady(
client,
1,
"app=kube-rbac-proxy",
),
kubetest.ServiceIsReady(
client,
"kube-rbac-proxy",
),
),
Then: kubetest.Actions(
kubetest.ClientSucceeds(
client,
legacyCommand,
&kubetest.RunOptions{TokenAudience: "kube-rbac-proxy"},
),
),
}.Run(t)

kubetest.Scenario{
Name: "LegacyDisallowedAudienceSet",
Description: `
As a client with --allow-legacy-serviceaccount-tokens=false and a valid audience,
I succeed with my request
`,

Given: kubetest.Actions(
kubetest.CreatedManifests(
client,
"legacy/clusterRole.yaml",
"legacy/clusterRoleBinding.yaml",
"legacy/deployment-disallowed.yaml",
"legacy/service.yaml",
"legacy/serviceAccount.yaml",
"legacy/clusterRole-client.yaml",
"legacy/clusterRoleBinding-client.yaml",
),
),
When: kubetest.Actions(
kubetest.PodsAreReady(
client,
1,
"app=kube-rbac-proxy",
),
kubetest.ServiceIsReady(
client,
"kube-rbac-proxy",
),
),
Then: kubetest.Actions(
kubetest.ClientSucceeds(
client,
legacyCommand,
&kubetest.RunOptions{TokenAudience: "kube-rbac-proxy"},
),
),
}.Run(t)

kubetest.Scenario{
Name: "LegacyAllowedNoAudience",
Description: `
As a client with --allow-legacy-serviceaccount-tokens=true and no audience set,
I succeed with my request
`,

Given: kubetest.Actions(
kubetest.CreatedManifests(
client,
"legacy/clusterRole.yaml",
"legacy/clusterRoleBinding.yaml",
"legacy/deployment-allowed-noaud.yaml",
"legacy/service.yaml",
"legacy/serviceAccount.yaml",
"legacy/clusterRole-client.yaml",
"legacy/clusterRoleBinding-client.yaml",
),
),
When: kubetest.Actions(
kubetest.PodsAreReady(
client,
1,
"app=kube-rbac-proxy",
),
kubetest.ServiceIsReady(
client,
"kube-rbac-proxy",
),
),
Then: kubetest.Actions(
kubetest.ClientSucceeds(
client,
command,
&kubetest.RunOptions{TokenAudience: ""},
),
),
}.Run(t)
}
}
1 change: 1 addition & 0 deletions test/e2e/basics/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ spec:
args:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--allow-legacy-serviceaccount-tokens=true"
- "--authentication-skip-lookup"
- "--v=10"
ports:
Expand Down
1 change: 1 addition & 0 deletions test/e2e/clientcertificates/deployment-wrongca.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--client-ca-file=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
- "--allow-legacy-serviceaccount-tokens=true"
- "--authentication-skip-lookup"
- "--v=10"
ports:
Expand Down
1 change: 1 addition & 0 deletions test/e2e/clientcertificates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--client-ca-file=/certs/ca.crt"
- "--allow-legacy-serviceaccount-tokens=true"
- "--authentication-skip-lookup"
- "--v=10"
ports:
Expand Down
1 change: 1 addition & 0 deletions test/e2e/h2c-upstream/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--authentication-skip-lookup"
- "--allow-legacy-serviceaccount-tokens=true"
- "--upstream-force-h2c=true"
- "--v=10"
ports:
Expand Down
1 change: 1 addition & 0 deletions test/e2e/http2/deployment-no-http2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--authentication-skip-lookup"
- "--allow-legacy-serviceaccount-tokens=true"
- "--ignore-paths=/metrics,/api/v1/*"
- "--disable-http2-serving=true"
- "--v=10"
Expand Down
1 change: 1 addition & 0 deletions test/e2e/http2/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:
- "--secure-port=8443"
- "--upstream=http://127.0.0.1:8081/"
- "--authentication-skip-lookup"
- "--allow-legacy-serviceaccount-tokens=true"
- "--ignore-paths=/metrics,/api/v1/*"
- "--v=10"
ports:
Expand Down
1 change: 1 addition & 0 deletions test/e2e/identityheaders/default/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ spec:
- "--auth-header-user-field-name=x-remote-user"
- "--auth-header-groups-field-name=x-remote-groups"
- "--auth-header-groups-field-separator=|"
- "--allow-legacy-serviceaccount-tokens=true"
- "--v=10"
ports:
- containerPort: 8443
Expand Down
1 change: 1 addition & 0 deletions test/e2e/identityheaders/insecure/deployment-proxy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ spec:
- "--auth-header-user-field-name=x-remote-user"
- "--auth-header-groups-field-name=x-remote-groups"
- "--auth-header-groups-field-separator=|"
- "--allow-legacy-serviceaccount-tokens=true"
- "--v=10"
ports:
- containerPort: 8443
Expand Down
1 change: 1 addition & 0 deletions test/e2e/identityheaders/secure/deployment-proxy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ spec:
- "--auth-header-user-field-name=x-remote-user"
- "--auth-header-groups-field-name=x-remote-groups"
- "--auth-header-groups-field-separator=|"
- "--allow-legacy-serviceaccount-tokens=true"
- "--tls-cert-file=/usr/local/etc/kube-rbac-proxy/server-certs/tls.crt"
- "--tls-private-key-file=/usr/local/etc/kube-rbac-proxy/server-certs/tls.key"
- "--upstream-ca-file=/usr/local/etc/kube-rbac-proxy/upstream-trust/ca.crt"
Expand Down
1 change: 1 addition & 0 deletions test/e2e/ignorepaths/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ spec:
- "--upstream=http://127.0.0.1:8081/"
- "--ignore-paths=/metrics,/api/v1/*"
- "--authentication-skip-lookup"
- "--allow-legacy-serviceaccount-tokens=true"
- "--v=10"
ports:
- containerPort: 8443
Expand Down
7 changes: 7 additions & 0 deletions test/e2e/legacy/clusterRole-client.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: metrics
rules:
- nonResourceURLs: ["/metrics"]
verbs: ["get"]
13 changes: 13 additions & 0 deletions test/e2e/legacy/clusterRole.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kube-rbac-proxy
rules:
- apiGroups: ["authentication.k8s.io"]
resources:
- tokenreviews
verbs: ["create"]
- apiGroups: ["authorization.k8s.io"]
resources:
- subjectaccessreviews
verbs: ["create"]
12 changes: 12 additions & 0 deletions test/e2e/legacy/clusterRoleBinding-client.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metrics
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: metrics
subjects:
- kind: ServiceAccount
name: default
namespace: default
12 changes: 12 additions & 0 deletions test/e2e/legacy/clusterRoleBinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kube-rbac-proxy
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-rbac-proxy
subjects:
- kind: ServiceAccount
name: kube-rbac-proxy
namespace: default
Loading

0 comments on commit a8e9da6

Please sign in to comment.