Skip to content

Commit e811afa

Browse files
committed
Working PoC
1 parent 81bb483 commit e811afa

File tree

4 files changed

+147
-181
lines changed

4 files changed

+147
-181
lines changed

120_kubernetes/oidc/README.md

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,73 @@
1-
# Authenticate GitLab CI jobs against Kubernetes using GitLab OIDC
2-
3-
XXX
4-
5-
## Prepare
6-
7-
Deploy a Kubernetes cluster with authentication configuration from `auth-config.yaml`:
8-
9-
```shell
10-
kind create cluster \
11-
--name gitlab-ci-oidc \
12-
--config kind.yaml \
13-
--wait 5m
14-
```
15-
16-
Deploy GitLab runner:
17-
18-
```shell
19-
helm repo add gitlab https://charts.gitlab.io
20-
helm repo update
21-
helm upgrade --install \
22-
gitlab-runner gitlab/gitlab-runner \
23-
--values values-gitlab-runner.yaml \
24-
--set runnerRegistrationToken=TOKEN \
25-
--wait \
26-
--timeout 5m
27-
```
1+
# Authenticate GitLab user and GitLab CI jobs against Kubernetes using GitLab OIDC
2+
3+
This demonstrates how to authenticate GitLab CI jobs against Kubernetes using GitLab OIDC
4+
5+
## Prerequisites
6+
7+
GitLab with...
8+
- a group called `foo`
9+
- a project called `bar` in group `foo`
10+
- an application for group `foo`
11+
12+
`kubectl` is configured with [`kubelogin`](https://github.com/int128/kubelogin) to authenticate against GitLab
13+
14+
## References
15+
16+
XXX https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration
17+
18+
XXX https://cel.dev/
19+
20+
XXX https://docs.gitlab.com/ee/integration/openid_connect_provider.html
21+
22+
XXX https://docs.gitlab.com/ee/ci/yaml/#id_tokens
23+
24+
XXX https://docs.gitlab.com/ee/ci/secrets/id_token_authentication.html
25+
26+
## Prepare
27+
28+
Deploy a Kubernetes cluster with authentication configuration from `auth-config.yaml`:
29+
30+
```shell
31+
kind create cluster \
32+
--name gitlab-ci-oidc \
33+
--config kind.yaml \
34+
--wait 5m
35+
```
36+
37+
Apply RBAC
38+
39+
```shell
40+
kubectl apply -f rbac.yaml
41+
```
42+
43+
## GitLab CI
44+
45+
Deploy GitLab runner
46+
47+
```shell
48+
helm repo add gitlab https://charts.gitlab.io
49+
helm repo update
50+
helm upgrade --install \
51+
gitlab-runner gitlab/gitlab-runner \
52+
--values values-gitlab-runner.yaml \
53+
--set runnerRegistrationToken=TOKEN \
54+
--wait \
55+
--timeout 5m
56+
```
57+
58+
Test pipeline based on `.gitlab-ci.yml`
59+
60+
## Test `kubectl`
61+
62+
Test RBAC without OIDC
63+
64+
```shell
65+
kubectl get pods --as gitlab:MyUserName --as-group gitlab:foo -A
66+
kubectl get pods --as gitlab-ci:project_path:foo/bar:ref_type:branch:ref:main -A
67+
```
68+
69+
Test with RBAC
70+
71+
```shell
72+
kubectl --user=gitlab-oidc get pods
73+
```

120_kubernetes/oidc/auth-config.yaml

Lines changed: 17 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,17 @@
1-
---
2-
apiVersion: apiserver.config.k8s.io/v1beta1
3-
kind: AuthenticationConfiguration
4-
jwt:
5-
- issuer:
6-
# url must be unique across all authenticators.
7-
# url must not conflict with issuer configured in --service-account-issuer.
8-
url: https://gitlab.example.com
9-
# audiences is the set of acceptable audiences the JWT must be issued to.
10-
# At least one of the entries must match the "aud" claim in presented JWTs.
11-
audiences:
12-
- gitlab_user_auth
13-
# this is required to be set to "MatchAny" when multiple audiences are specified.
14-
audienceMatchPolicy: MatchAny
15-
claimMappings:
16-
# username represents an option for the username attribute.
17-
# This is the only required attribute.
18-
username:
19-
# Same as --oidc-username-claim. Mutually exclusive with username.expression.
20-
claim: preferred_username
21-
# Same as --oidc-username-prefix. Mutually exclusive with username.expression.
22-
# if username.claim is set, username.prefix is required.
23-
# Explicitly set it to "" if no prefix is desired.
24-
prefix: "oidc:"
25-
# groups represents an option for the groups attribute.
26-
groups:
27-
# Same as --oidc-groups-claim. Mutually exclusive with groups.expression.
28-
claim: groups_direct
29-
# Same as --oidc-groups-prefix. Mutually exclusive with groups.expression.
30-
# if groups.claim is set, groups.prefix is required.
31-
# Explicitly set it to "" if no prefix is desired.
32-
prefix: "gitlab:"
33-
# uid represents an option for the uid attribute.
34-
uid:
35-
# Mutually exclusive with uid.expression.
36-
claim: preferred_username
37-
- issuer:
38-
# url must be unique across all authenticators.
39-
# url must not conflict with issuer configured in --service-account-issuer.
40-
url: https://gitlab.example.com/
41-
# audiences is the set of acceptable audiences the JWT must be issued to.
42-
# At least one of the entries must match the "aud" claim in presented JWTs.
43-
audiences:
44-
- gitlab_ci_auth
45-
# this is required to be set to "MatchAny" when multiple audiences are specified.
46-
audienceMatchPolicy: MatchAny
47-
claimMappings:
48-
# username represents an option for the username attribute.
49-
# This is the only required attribute.
50-
username:
51-
# Same as --oidc-username-claim. Mutually exclusive with username.expression.
52-
claim: sub
53-
# Same as --oidc-username-prefix. Mutually exclusive with username.expression.
54-
# if username.claim is set, username.prefix is required.
55-
# Explicitly set it to "" if no prefix is desired.
56-
prefix: "gitlab-ci:"
57-
# groups represents an option for the groups attribute.
58-
groups:
59-
# Same as --oidc-groups-claim. Mutually exclusive with groups.expression.
60-
claim: namespace_path
61-
# Same as --oidc-groups-prefix. Mutually exclusive with groups.expression.
62-
# if groups.claim is set, groups.prefix is required.
63-
# Explicitly set it to "" if no prefix is desired.
64-
prefix: "gitlab-ci:"
65-
# uid represents an option for the uid attribute.
66-
uid:
67-
# Mutually exclusive with uid.expression.
68-
claim: sub
69-
# extra attributes to be added to the UserInfo object. Keys must be domain-prefix path and must be unique.
70-
#extra:
71-
# # key is a string to use as the extra attribute key.
72-
# # key must be a domain-prefix path (e.g. example.org/foo). All characters before the first "/" must be a valid
73-
# # subdomain as defined by RFC 1123. All characters trailing the first "/" must
74-
# # be valid HTTP Path characters as defined by RFC 3986.
75-
# # k8s.io, kubernetes.io and their subdomains are reserved for Kubernetes use and cannot be used.
76-
# # key must be lowercase and unique across all extra attributes.
77-
#- key: gitlab.haufedev.systems/namespace
78-
# valueExpression: namespace_id
79-
#- key: gitlab.haufedev.systems/project
80-
# valueExpression: project_id
81-
#- key: gitlab.haufedev.systems/triggerer
82-
# valueExpression: user_id
83-
#- key: gitlab.haufedev.systems/pipeline
84-
# valueExpression: pipeline_id
85-
#- key: gitlab.haufedev.systems/job
86-
# valueExpression: job_id
87-
#- key: gitlab.haufedev.systems/runner
88-
# valueExpression: runner_id
89-
#- key: gitlab.haufedev.systems/ref
90-
# valueExpression: ref
91-
#- key: gitlab.haufedev.systems/sha
92-
# valueExpression: sha
1+
---
2+
apiVersion: apiserver.config.k8s.io/v1beta1
3+
kind: AuthenticationConfiguration
4+
jwt:
5+
- issuer:
6+
url: https://gitlab.example.com
7+
audiences:
8+
- group_application_id
9+
- id_token_audience
10+
audienceMatchPolicy: MatchAny
11+
claimMappings:
12+
username:
13+
expression: 'has(claims.preferred_username) ? "gitlab:" + claims.preferred_username : "gitlab-ci:" + claims.sub'
14+
groups:
15+
expression: 'has(claims.groups_direct) ? "gitlab:" + claims.groups_direct : "gitlab-ci:" + claims.namespace_path'
16+
uid:
17+
expression: 'has(claims.preferred_username) ? "gitlab:" + claims.preferred_username : "gitlab-ci:" + claims.sub'

120_kubernetes/oidc/rbac.yaml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22
kind: ClusterRoleBinding
33
apiVersion: rbac.authorization.k8s.io/v1
44
metadata:
5-
name: oidc-cluster-admin
5+
name: oidc-viewer
66
roleRef:
77
apiGroup: rbac.authorization.k8s.io
88
kind: ClusterRole
9-
name: cluster-admin
9+
name: view
1010
subjects:
11-
- kind: Group
12-
name: gitlab:k8s-oidc-demo
11+
- kind: User
12+
name: gitlab-ci:project_path:foo/bar:ref_type:branch:ref:main
13+
- kind: User
14+
name: gitlab:MyUserName
1315
---
1416
kind: ClusterRoleBinding
1517
apiVersion: rbac.authorization.k8s.io/v1
1618
metadata:
17-
name: oidc-test
19+
name: oidc-admin
1820
roleRef:
1921
apiGroup: rbac.authorization.k8s.io
2022
kind: ClusterRole
21-
name: view
23+
name: cluster-admin
2224
subjects:
23-
- kind: User
24-
name: gitlab-ci:project_path:DilleN/foo:ref_type:branch:ref:main
25+
- kind: Group
26+
name: gitlab:foo
Lines changed: 47 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,47 @@
1-
image:
2-
registry: registry.gitlab.com
3-
image: gitlab-org/gitlab-runner
4-
#tag: alpine-v16.4.0
5-
imagePullPolicy: Always
6-
probeTimeoutSeconds: 5
7-
8-
## How many runner pods to launch.
9-
##
10-
## Note: Using more than one replica is not supported with a runnerToken. Use a runnerRegistrationToken
11-
## to create multiple runner replicas.
12-
# replicas: 1
13-
14-
gitlabUrl: https://gitlab.example.com/
15-
16-
unregisterRunners: true
17-
terminationGracePeriodSeconds: 3600
18-
concurrent: 5
19-
checkInterval: 5
20-
21-
rbac:
22-
create: true
23-
rules:
24-
- resources: ["pods", "secrets", "configmaps"]
25-
verbs: ["get", "list", "watch", "create", "patch", "delete", "update"]
26-
- apiGroups: [""]
27-
resources: ["pods/attach", "pods/exec"]
28-
verbs: ["create", "patch", "delete"]
29-
clusterWideAccess: false
30-
podSecurityPolicy:
31-
enabled: false
32-
resourceNames:
33-
- gitlab-runner
34-
35-
runners:
36-
config: |
37-
[[runners]]
38-
executor = "kubernetes"
39-
40-
[runners.kubernetes]
41-
image = "alpine"
42-
locked: false
43-
44-
securityContext:
45-
allowPrivilegeEscalation: false
46-
readOnlyRootFilesystem: false
47-
runAsNonRoot: true
48-
privileged: false
49-
capabilities:
50-
drop: ["ALL"]
51-
52-
podSecurityContext:
53-
runAsUser: 100
54-
fsGroup: 65533
1+
image:
2+
registry: registry.gitlab.com
3+
image: gitlab-org/gitlab-runner
4+
#tag: alpine-v16.4.0
5+
imagePullPolicy: Always
6+
probeTimeoutSeconds: 5
7+
8+
gitlabUrl: https://gitlab.example.com/
9+
unregisterRunners: true
10+
terminationGracePeriodSeconds: 3600
11+
concurrent: 5
12+
checkInterval: 5
13+
14+
rbac:
15+
create: true
16+
rules:
17+
- resources: ["pods", "secrets", "configmaps"]
18+
verbs: ["get", "list", "watch", "create", "patch", "delete", "update"]
19+
- apiGroups: [""]
20+
resources: ["pods/attach", "pods/exec"]
21+
verbs: ["create", "patch", "delete"]
22+
clusterWideAccess: false
23+
podSecurityPolicy:
24+
enabled: false
25+
resourceNames:
26+
- gitlab-runner
27+
28+
runners:
29+
config: |
30+
[[runners]]
31+
executor = "kubernetes"
32+
33+
[runners.kubernetes]
34+
image = "alpine"
35+
locked: false
36+
37+
securityContext:
38+
allowPrivilegeEscalation: false
39+
readOnlyRootFilesystem: false
40+
runAsNonRoot: true
41+
privileged: false
42+
capabilities:
43+
drop: ["ALL"]
44+
45+
podSecurityContext:
46+
runAsUser: 100
47+
fsGroup: 65533

0 commit comments

Comments
 (0)