Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions README-fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,45 @@ kubectl describe svc vtom-server -n vtom
# Côté cloud : vérifier annotations et quotas LB
```

# Sécurité

## Conformité

Ce chart est conforme aux référentiels suivants :

- **Kubernetes Pod Security Standards (PSS) — profil `restricted`** (tous les pods)
- **CIS Kubernetes Benchmark — Level 1** (tous les contrôles applicables)

### Contrôles en place

| Contrôle | Détail |
|---|---|
| `runAsNonRoot: true` | Tous les pods |
| `runAsUser` / `runAsGroup` non nuls | uid=1000 / gid=1000 (vtom), uid=10001 (ITC, ITM, MFT) |
| `fsGroup` non nul | 1000 sur les composants VTOM core ; 10001 sur ITC, ITM, MFT |
| `allowPrivilegeEscalation: false` | Tous les conteneurs, y compris les init containers et sidecars |
| `capabilities.drop: ["ALL"]` | Tous les conteneurs, y compris les init containers et sidecars |
| `seccompProfile: RuntimeDefault` | Tous les pods |
| `readOnlyRootFilesystem: true` | Init containers et sidecar proxy DB |
| `automountServiceAccountToken: false` | Tous les pods |
| NetworkPolicies — deny par défaut | Ingress et egress bloqués par défaut ; règles d'autorisation explicites par composant |
| Secrets via `secretKeyRef` | Aucune donnée sensible dans les ConfigMaps ou variables d'environnement |
| `defaultMode: 0440` sur les volumes secrets | Fichiers de licence montés en lecture seule |

### Exception documentée (CIS Level 2)

`readOnlyRootFilesystem` n'est pas activé sur les conteneurs applicatifs principaux (vtom-server, vtom-agent, vtom-apiserver, ITC, ITM). Ces composants écrivent sur leur système de fichiers à l'exécution, ce qui constitue une contrainte image upstream. Ce contrôle est classé **Level 2** dans le CIS Benchmark et son absence est compensée par les contrôles listés ci-dessus.

### Pod Security Admission

Pour appliquer le profil PSS `restricted` au niveau du namespace, ajouter le label suivant à la création du namespace :

```bash
kubectl label namespace vtom \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted
```

# Licence

Ce projet est sous licence Apache 2.0. Voir le fichier [LICENSE](LICENSE) pour plus de détails.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,45 @@ kubectl describe svc vtom-server -n vtom
# Cloud side: check annotations and LB quotas
```

# Security

## Compliance

This chart is compliant with:

- **Kubernetes Pod Security Standards (PSS) — `restricted` profile** (all pods)
- **CIS Kubernetes Benchmark — Level 1** (all applicable controls)

### Controls in place

| Control | Detail |
|---|---|
| `runAsNonRoot: true` | All pods |
| `runAsUser` / `runAsGroup` non-zero | uid=1000 / gid=1000 (vtom), uid=10001 (ITC, ITM, MFT) |
| `fsGroup` non-zero | 1000 on VTOM core; 10001 on ITC, ITM, MFT |
| `allowPrivilegeEscalation: false` | All containers, including init containers and sidecars |
| `capabilities.drop: ["ALL"]` | All containers, including init containers and sidecars |
| `seccompProfile: RuntimeDefault` | All pods |
| `readOnlyRootFilesystem: true` | Init containers and DB proxy sidecar |
| `automountServiceAccountToken: false` | All pods |
| NetworkPolicies — default deny | Ingress and egress blocked by default; explicit allow rules per component |
| Secrets via `secretKeyRef` | No credentials in ConfigMaps or environment variables |
| Secret volume `defaultMode: 0440` | License files mounted read-only |

### Known exception (CIS Level 2)

`readOnlyRootFilesystem` is not set on the main application containers (vtom-server, vtom-agent, vtom-apiserver, ITC, ITM). These components write to their filesystem at runtime, which is an upstream image constraint. This control is classified **Level 2** in the CIS Benchmark and its absence is compensated by the controls listed above.

### Pod Security Admission

To enforce the `restricted` PSS profile at the namespace level, add the following label when creating the namespace:

```bash
kubectl label namespace vtom \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted
```

# License

This project is licensed under the Apache 2.0 License — see the [LICENSE](LICENSE) file for details.
3 changes: 2 additions & 1 deletion charts/visual-tom/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ description: >
type: application

# Chart version (follows SemVer). Increment on every chart change.
version: 0.2.4
version: 0.2.5


# Reference application version (VTOM). ITC, ITM and MFT versions are defined in values.yaml.
appVersion: "7.3.2c"
Expand Down
1 change: 1 addition & 0 deletions charts/visual-tom/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ Rendered only when dbProxy.enabled=true.
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
{{- end }}
Expand Down
5 changes: 4 additions & 1 deletion charts/visual-tom/templates/vtom/deployment-agent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ spec:
{{- if .Values.securityContext.runAsUser }}
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
fsGroup: 0
{{- if .Values.securityContext.runAsGroup }}
runAsGroup: {{ .Values.securityContext.runAsGroup }}
{{- end }}
fsGroup: {{ .Values.securityContext.fsGroup | default 0 }}
seccompProfile:
type: RuntimeDefault
containers:
Expand Down
5 changes: 4 additions & 1 deletion charts/visual-tom/templates/vtom/deployment-apiserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ spec:
{{- if .Values.securityContext.runAsUser }}
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
fsGroup: 0
{{- if .Values.securityContext.runAsGroup }}
runAsGroup: {{ .Values.securityContext.runAsGroup }}
{{- end }}
fsGroup: {{ .Values.securityContext.fsGroup | default 0 }}
seccompProfile:
type: RuntimeDefault
initContainers:
Expand Down
5 changes: 4 additions & 1 deletion charts/visual-tom/templates/vtom/deployment-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ spec:
{{- if .Values.securityContext.runAsUser }}
runAsUser: {{ .Values.securityContext.runAsUser }}
{{- end }}
fsGroup: 0
{{- if .Values.securityContext.runAsGroup }}
runAsGroup: {{ .Values.securityContext.runAsGroup }}
{{- end }}
fsGroup: {{ .Values.securityContext.fsGroup | default 0 }}
seccompProfile:
type: RuntimeDefault
initContainers:
Expand Down
4 changes: 3 additions & 1 deletion charts/visual-tom/values-aws.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ tls:
clusterIssuer: letsencrypt-prod

securityContext:
runAsUser: 1000 # UID of the vtom user in Absyss images
runAsUser: 1000 # uid=1000(vtom) — confirmed from running image (kubectl exec id)
runAsGroup: 1000 # gid=1000(vtom) — confirmed from running image
fsGroup: 1000

networkPolicy:
enabled: true
Expand Down
4 changes: 3 additions & 1 deletion charts/visual-tom/values-azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ tls:
clusterIssuer: letsencrypt-prod

securityContext:
runAsUser: 1000 # UID of the vtom user in Absyss images
runAsUser: 1000 # uid=1000(vtom) — confirmed from running image (kubectl exec id)
runAsGroup: 1000 # gid=1000(vtom) — confirmed from running image
fsGroup: 1000

networkPolicy:
enabled: true
Expand Down
4 changes: 3 additions & 1 deletion charts/visual-tom/values-gcp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ tls:
clusterIssuer: letsencrypt-prod

securityContext:
runAsUser: 1000 # UID of the vtom user in Absyss images
runAsUser: 1000 # uid=1000(vtom) — confirmed from running image (kubectl exec id)
runAsGroup: 1000 # gid=1000(vtom) — confirmed from running image
fsGroup: 1000

networkPolicy:
enabled: true
Expand Down
6 changes: 4 additions & 2 deletions charts/visual-tom/values-onpremise.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ tls:
clusterIssuer: letsencrypt-prod

securityContext:
runAsUser: 1000 # UID of the vtom user in Absyss images
# Leave null on OpenShift (nonroot SCC manages the UID)
runAsUser: 1000 # uid=1000(vtom) — confirmed from running image (kubectl exec id)
runAsGroup: 1000 # gid=1000(vtom) — confirmed from running image
fsGroup: 1000
# Leave all three null on OpenShift (nonroot SCC manages the UID/GID automatically)

networkPolicy:
enabled: true
Expand Down
17 changes: 10 additions & 7 deletions charts/visual-tom/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -532,16 +532,19 @@ networkPolicy:

# -----------------------------------------------------------------------------
# Pod security context — applies to VTOM components only (server, apiserver, agent).
# runAsUser: numeric UID required on standard K8s when the image uses a symbolic
# user (e.g.: USER vtom) — K8s cannot verify runAsNonRoot without a numeric UID.
# Leave null on OpenShift: the nonroot SCC assigns the UID automatically from the
# namespace range, avoiding conflicts with a hardcoded UID.
# Recommended value for VTOM images (server, apiserver, agent): 1000 (set in values-<cloud>.yaml).
# ITC, ITM and MFT run under their own hardcoded uid 10001 (absyss) in their templates
# and ignore this value.
# runAsUser / runAsGroup: numeric UID/GID required on standard K8s when the image uses
# a symbolic user (e.g.: USER vtom) — K8s cannot verify runAsNonRoot without a numeric UID.
# fsGroup: controls volume ownership on mounted PVCs.
# Leave all three null on OpenShift: the nonroot SCC assigns the UID automatically from
# the namespace range, avoiding conflicts with a hardcoded value.
# Confirmed values for VTOM images (server, apiserver, agent): uid=1000 gid=1000 (set in
# values-<cloud>.yaml). ITC, ITM and MFT run under their own hardcoded uid/gid 10001 and
# ignore these values.
# -----------------------------------------------------------------------------
securityContext:
runAsUser: null
runAsGroup: null
fsGroup: null

# -----------------------------------------------------------------------------
# PodDisruptionBudget
Expand Down