Skip to content

Commit 95eaae1

Browse files
committed
feat(docs): improve setup and ecosystem
1 parent 86b9f6b commit 95eaae1

25 files changed

Lines changed: 791 additions & 666 deletions

config/_default/hugo.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,22 @@ menu:
159159
pre: <i class='fas fa-users'></i>
160160
weight: 13
161161

162+
- name: Live-Demo
163+
url: https://killercoda.com/peak-scale-test/course/playgrounds/capsule
164+
pre: <i class='fas fa-terminal'></i>
165+
weight: 14
166+
162167
- name: Resources
163168
url: /resources/
164169
pre: <i class='fa-brands fa-readme'></i>
165-
weight: 14
170+
weight: 15
166171

167172
- name: Support
168173
url: /support/
169174
pre: <i class='fas fa-briefcase'></i>
170-
weight: 15
175+
weight: 16
171176

172177
- name: Project
173178
url: /project/
174179
pre: <i class='fas fa-flask'></i>
175-
weight: 16
180+
weight: 17

content/en/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ title: Project Capsule
1212
</a>
1313

1414
<a class="btn btn-lg btn-primary me-3 mb-4" href="https://killercoda.com/peak-scale-test/course/playgrounds/capsule">
15-
Demo <i class="fas fa-arrow-alt-circle-right ms-2"></i>
15+
Live-Demo <i class="fas fa-arrow-alt-circle-right ms-2"></i>
1616
</a>
1717
</div>
1818

content/en/docs/operating/authentication.md

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Integrate Capsule with Authentication of your Kubernetes cluster
44
weight: 5
55
---
66

7-
Capsule does not care about the authentication strategy used in the cluster and all the Kubernetes methods of authentication are supported. The only requirement to use Capsule is to assign tenant users to the group defined by userGroups option in the CapsuleConfiguration, which defaults to capsule.clastix.io.
7+
Capsule does not care about the authentication strategy used in the cluster and all the Kubernetes methods of authentication are supported. The only requirement to use Capsule is to assign tenant users to the group defined by userGroups option in the CapsuleConfiguration, which defaults to `projectcapsule.dev`.
88

99
## OIDC
1010

@@ -15,16 +15,17 @@ In the following guide, we'll use [Keycloak](https://www.keycloak.org/) an Open
1515
Configure Keycloak as OIDC server:
1616

1717
* Add a realm called caas, or use any existing realm instead
18-
* Add a group capsule.clastix.io
19-
* Add a user alice assigned to group capsule.clastix.io
20-
* Add an OIDC client called kubernetes
18+
* Add a group `projectcapsule.dev`
19+
* Add a user alice assigned to group `projectcapsule.dev`
20+
* Add an OIDC client called `kubernetes` (Public)
21+
* Add an OIDC client called `kubernetes-auth` (Confidential (Client Secret))
2122

2223
For the kubernetes client, create protocol mappers called groups and audience
2324
If everything is done correctly, now you should be able to authenticate in Keycloak and see user groups in JWT tokens. Use the following snippet to authenticate in Keycloak as alice user:
2425

2526
```bash
2627
$ KEYCLOAK=sso.clastix.io
27-
$ REALM=caas
28+
$ REALM=kubernetes-auth
2829
$ OIDC_ISSUER=${KEYCLOAK}/realms/${REALM}
2930

3031
$ curl -k -s https://${OIDC_ISSUER}/protocol/openid-connect/token \
@@ -54,7 +55,7 @@ To introspect the `ID_TOKEN` token run:
5455
```bash
5556
$ curl -k -s https://${OIDC_ISSUER}/protocol/openid-connect/introspect \
5657
-d token=${ID_TOKEN} \
57-
--user ${OIDC_CLIENT_ID}:${OIDC_CLIENT_SECRET} | jq
58+
--user kubernetes-auth:${OIDC_CLIENT_SECRET} | jq
5859
```
5960

6061
The result will be like the following:
@@ -82,6 +83,45 @@ The result will be like the following:
8283

8384
Configuring Kubernetes for OIDC Authentication requires adding several parameters to the API Server. Please, refer to the [documentation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens) for details and examples. Most likely, your kube-apiserver.yaml manifest will looks like the following:
8485

86+
#### Authentication Configuration (Recommended)
87+
88+
The configuration file approach allows you to configure multiple JWT authenticators, each with a unique issuer.url and issuer.discoveryURL. The configuration file even allows you to specify CEL expressions to map claims to user attributes, and to validate claims and user information.
89+
90+
```yaml
91+
apiVersion: apiserver.config.k8s.io/v1beta1
92+
kind: AuthenticationConfiguration
93+
jwt:
94+
- issuer:
95+
url: https://${OIDC_ISSUER}
96+
audiences:
97+
- kubernetes
98+
- kubernetes-auth
99+
audienceMatchPolicy: MatchAny
100+
claimMappings:
101+
username:
102+
claim: 'email'
103+
prefix: ""
104+
groups:
105+
claim: 'groups'
106+
prefix: ""
107+
certificateAuthority: <PEM encoded CA certificates>
108+
```
109+
110+
This file must be present and consistent across all kube-apiserver instances in the cluster. Add the following flag to the kube-apiserver manifest:
111+
112+
```yaml
113+
spec:
114+
containers:
115+
- command:
116+
- kube-apiserver
117+
...
118+
- --authentication-configuration-file=/etc/kubernetes/authentication/authentication.yaml
119+
```
120+
121+
[Read More](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration)
122+
123+
#### OIDC Flags (Legacy)
124+
85125
```yaml
86126
spec:
87127
containers:
@@ -90,7 +130,7 @@ spec:
90130
...
91131
- --oidc-issuer-url=https://${OIDC_ISSUER}
92132
- --oidc-ca-file=/etc/kubernetes/oidc/ca.crt
93-
- --oidc-client-id=${OIDC_CLIENT_ID}
133+
- --oidc-client-id=kubernetes
94134
- --oidc-username-claim=preferred_username
95135
- --oidc-groups-claim=groups
96136
- --oidc-username-prefix=-
@@ -112,7 +152,7 @@ nodes:
112152
extraArgs:
113153
oidc-issuer-url: https://${OIDC_ISSUER}
114154
oidc-username-claim: preferred_username
115-
oidc-client-id: ${OIDC_CLIENT_ID}
155+
oidc-client-id: kubernetes
116156
oidc-username-prefix: "keycloak:"
117157
oidc-groups-claim: groups
118158
oidc-groups-prefix: "keycloak:"
@@ -133,7 +173,7 @@ One way to use OIDC authentication is the use of a kubectl plugin. The [Kubelogi
133173
```shell
134174
kubectl oidc-login setup \
135175
--oidc-issuer-url=https://${OIDC_ISSUER} \
136-
--oidc-client-id=${OIDC_CLIENT_ID} \
176+
--oidc-client-id=kubernetes-auth \
137177
--oidc-client-secret=${OIDC_CLIENT_SECRET}
138178
```
139179

@@ -146,7 +186,7 @@ $ kubectl config set-credentials oidc \
146186
--auth-provider=oidc \
147187
--auth-provider-arg=idp-issuer-url=https://${OIDC_ISSUER} \
148188
--auth-provider-arg=idp-certificate-authority=/path/to/ca.crt \
149-
--auth-provider-arg=client-id=${OIDC_CLIENT_ID} \
189+
--auth-provider-arg=client-id=kubernetes-auth \
150190
--auth-provider-arg=client-secret=${OIDC_CLIENT_SECRET} \
151191
--auth-provider-arg=refresh-token=${REFRESH_TOKEN} \
152192
--auth-provider-arg=id-token=${ID_TOKEN} \

content/en/docs/operating/best-practices/control-pod-security.md renamed to content/en/docs/operating/best-practices/workloads.md

Lines changed: 74 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,88 @@
11
---
2-
title: Pod Security Standards
2+
title: Workloads
33
weight: 3
4-
description: Control the security of the pods running in the tenant namespaces
4+
description: Control the security of the workloads running in the tenant namespaces
55
---
66

7+
## User Namespaces
8+
9+
{{% alert title="Info" color="info" %}}
10+
The FeatureGate `UserNamespacesSupport` is active by default since [Kubernetes 1.33](https://kubernetes.io/blog/2025/04/25/userns-enabled-by-default/). However every pod must still [opt-in](#admission)
11+
12+
When you are also enabling the FeatureGate `UserNamespacesPodSecurityStandards` you may relax the Pod Security Standards for your workloads. [Read More](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/#integration-with-pod-security-admission-checks)
13+
{{% /alert %}}
14+
15+
A process running as root in a container can run as a different (non-root) user in the host; in other words, the process has full privileges for operations inside the user namespace, but is unprivileged for operations outside the namespace. [Read More](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/)
16+
17+
### Kubelet
18+
19+
On your Kubelet you must use the [FeatureGates](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/):
20+
21+
* `UserNamespacesSupport`
22+
* `UserNamespacesPodSecurityStandards` (Optional)
23+
24+
### Sysctls
25+
26+
```yaml
27+
user.max_user_namespaces: "11255"
28+
```
29+
30+
### Admission (Kyverno)
31+
32+
To make sure all the workloads are forced to use dedicated User Namespaces, we recommend to mutate pods at admission. See the following examples.
33+
34+
#### Kyverno
35+
36+
```yaml
37+
apiVersion: kyverno.io/v1
38+
kind: ClusterPolicy
39+
metadata:
40+
name: add-hostusers-spec
41+
annotations:
42+
policies.kyverno.io/title: Add HostUsers
43+
policies.kyverno.io/category: Security
44+
policies.kyverno.io/subject: Pod,User Namespace
45+
kyverno.io/kubernetes-version: "1.31"
46+
policies.kyverno.io/description: >-
47+
Do not use the host's user namespace. A new userns is created for the pod.
48+
Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root
49+
without actually having root privileges on the host. This field is
50+
alpha-level and is only honored by servers that enable the
51+
UserNamespacesSupport feature.
52+
spec:
53+
rules:
54+
- name: add-host-users
55+
match:
56+
any:
57+
- resources:
58+
kinds:
59+
- Pod
60+
namespaceSelector:
61+
matchExpressions:
62+
- key: capsule.clastix.io/tenant
63+
operator: Exists
64+
preconditions:
65+
all:
66+
- key: "{{request.operation || 'BACKGROUND'}}"
67+
operator: AnyIn
68+
value:
69+
- CREATE
70+
- UPDATE
71+
mutate:
72+
patchStrategicMerge:
73+
spec:
74+
hostUsers: false
75+
```
76+
77+
## Pod Security Standards
78+
779
In Kubernetes, by default, workloads run with administrative access, which might be acceptable if there is only a single application running in the cluster or a single user accessing it. This is seldom required and you’ll consequently suffer a noisy neighbour effect along with large security blast radiuses.
880
981
Many of these concerns were addressed initially by [PodSecurityPolicies](https://kubernetes.io/docs/concepts/security/pod-security-policy) which have been present in the Kubernetes APIs since the very early days.
1082
1183
The Pod Security Policies are deprecated in Kubernetes 1.21 and removed entirely in 1.25. As replacement, the [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) and [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/) has been introduced. Capsule support the new standard for tenants under its control as well as the oldest approach.
1284
1385
14-
## Pod Security Standards
1586
One of the issues with Pod Security Policies is that it is difficult to apply restrictive permissions on a granular level, increasing security risk. Also the Pod Security Policies get applied when the request is submitted and there is no way of applying them to pods that are already running. For these, and other reasons, the Kubernetes community decided to deprecate the Pod Security Policies.
1687
1788
As the Pod Security Policies get deprecated and removed, the [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/) is used in place. It defines three different policies to broadly cover the security spectrum. These policies are cumulative and range from highly-permissive to highly-restrictive:
@@ -165,76 +236,6 @@ kubectl --kubeconfig alice-solar.kubeconfig label ns solar-production \
165236
Error from server (Label pod-security.kubernetes.io/audit is forbidden for namespaces in the current Tenant ...
166237
```
167238

168-
## User Namespaces
169-
170-
{{% alert title="Info" color="info" %}}
171-
The FeatureGate `UserNamespacesSupport` is active by default since [Kubernetes 1.33](https://kubernetes.io/blog/2025/04/25/userns-enabled-by-default/). However every pod must still [opt-in](#admission)
172-
173-
When you are also enabling the FeatureGate `UserNamespacesPodSecurityStandards` you may relax the Pod Security Standards for your workloads. [Read More](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/#integration-with-pod-security-admission-checks)
174-
{{% /alert %}}
175-
176-
A process running as root in a container can run as a different (non-root) user in the host; in other words, the process has full privileges for operations inside the user namespace, but is unprivileged for operations outside the namespace. [Read More](https://kubernetes.io/docs/concepts/workloads/pods/user-namespaces/)
177-
178-
### Kubelet
179-
180-
On your Kubelet you must use the [FeatureGates](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/):
181-
182-
* `UserNamespacesSupport`
183-
* `UserNamespacesPodSecurityStandards` (Optional)
184-
185-
### Sysctls
186-
187-
```yaml
188-
user.max_user_namespaces: "11255"
189-
```
190-
191-
### Admission (Kyverno)
192-
193-
To make sure all the workloads are forced to use dedicated User Namespaces, we recommend to mutate pods at admission. See the following examples.
194-
195-
#### Kyverno
196-
197-
```yaml
198-
apiVersion: kyverno.io/v1
199-
kind: ClusterPolicy
200-
metadata:
201-
name: add-hostusers-spec
202-
annotations:
203-
policies.kyverno.io/title: Add HostUsers
204-
policies.kyverno.io/category: Security
205-
policies.kyverno.io/subject: Pod,User Namespace
206-
kyverno.io/kubernetes-version: "1.31"
207-
policies.kyverno.io/description: >-
208-
Do not use the host's user namespace. A new userns is created for the pod.
209-
Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root
210-
without actually having root privileges on the host. This field is
211-
alpha-level and is only honored by servers that enable the
212-
UserNamespacesSupport feature.
213-
spec:
214-
rules:
215-
- name: add-host-users
216-
match:
217-
any:
218-
- resources:
219-
kinds:
220-
- Pod
221-
namespaceSelector:
222-
matchExpressions:
223-
- key: capsule.clastix.io/tenant
224-
operator: Exists
225-
preconditions:
226-
all:
227-
- key: "{{request.operation || 'BACKGROUND'}}"
228-
operator: AnyIn
229-
value:
230-
- CREATE
231-
- UPDATE
232-
mutate:
233-
patchStrategicMerge:
234-
spec:
235-
hostUsers: false
236-
```
237-
238239
## Pod Security Policies
239240

240241
As stated in the documentation, *"PodSecurityPolicies enable fine-grained authorization of pod creation and updates. A Pod Security Policy is a cluster-level resource that controls security sensitive aspects of the pod specification. The `PodSecurityPolicy` objects define a set of conditions that a pod must run with in order to be accepted into the system, as well as defaults for the related fields."*

content/en/docs/operating/installation/_index.md

Lines changed: 0 additions & 12 deletions
This file was deleted.

content/en/docs/operating/installation/upgrading.md

Lines changed: 0 additions & 38 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Setup
3+
weight: 1
4+
description: "Setting up your environment for Capsule"
5+
type: docs
6+
weight: 1
7+
---

0 commit comments

Comments
 (0)