Organisation and people
Security policy, roles, clearances and training of the staff. OpenKeel provides named roles and the audit trail of their actions.
OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent
Architecture
OpenKeel is designed to be SecNumCloud-ready: what is compliant today, what is in progress and what is left to evolve, requirement by requirement, each with its evidence in the code.
SecNumCloud (ANSSI, framework 3.2) qualifies a service run by a provider, not a piece of software. The framework covers organisation, human resources, physical security, operations, incident management and protection from extra-European law (§ 19.6) as much as technique.
OpenKeel therefore cannot be "SecNumCloud qualified". It aims to be a SecNumCloud-ready foundation: software that blocks no technical requirement of the framework, provides the expected mechanisms (traceability, segregation, encryption, strong authentication) and the documentation that lets the provider demonstrate compliance during the audit.
Counted from the tables below; the provider's share is listed apart.
An internal PKI run by cert-manager (issuer openkeel-ca) signs the services' certificates; the MariaDB operator's CA signs the database's. Every service verifies the server it talks to.
| Flow | Protocol | Trust |
|---|---|---|
| Clients → Ingress → APIs | HTTPS, re-encrypted to HTTPS backends (Skyline, Nova console, Zun wsproxy) | Public certificate; internal cert-manager certificates |
| API ↔ API | REST over HTTPS, https internal URLs in the catalog | Internal PKI, cert-manager issuer openkeel-ca |
| Services → MariaDB | SQL over TLS, required by the server | CA of the MariaDB operator, verified by every service |
| Services → RabbitMQ | AMQPS (RPC and notifications) | Internal PKI openkeel-ca |
| Neutron → OVN NB/SB | OVSDB over ssl:, mutual TLS | OVN client and server certificates |
No Memcached and no Redis any more: no component read them, and okadm removes them from existing installations. Only the admin ports :9090 (health, metrics), the Erlang distribution between the RabbitMQ nodes and the RGW gateway of --ceph-s3 still serve plain traffic inside the cluster. The whole table is in the code (global.tls.internal, on by default) and was verified on the lab on 2026-11-08.
Every image a production cluster runs comes from the provider's registry: OpenKeel's own, built from the workspace, and the third-party ones, copied there with their SBOM. Both are signed with the provider's key.
| Images | Registry | SBOM and provenance | Signature |
|---|---|---|---|
OpenKeel services, okadm, web site | Built by make release and pushed to REGISTRY; the charts point to it (global.imageRegistry) | SPDX SBOM per platform and SLSA provenance, attached by BuildKit in the image index; exported by make sbom | cosign, by digest of the index (make sign), covering the attestations |
okadm binaries | Release files in dist/cli, with SHA256SUMS | SPDX SBOM per binary (syft) | Checksums |
| Prerequisites: cert-manager, MariaDB and RabbitMQ operators, MariaDB, RabbitMQ, Traefik | Copied registry to registry by make mirror-prereqs, every platform, one prefix per upstream registry | The publisher's SBOM when the copy keeps one, otherwise a syft SBOM attached with cosign attest (MIRROR_SBOM=1) | Every copy signed with the OpenKeel key |
| Ironic (upstream Kolla images) | Pinned by digest in okadm's release manifest, pulled through global.imageRegistry | Through the mirror (MIRROR_EXTRA_IMAGES) | Through the mirror |
The cluster pulls from the mirror without any chart change: one hosts.toml per upstream registry for containerd, machine.registries.mirrors under Talos. No signature, SBOM or image digest is sent to the public Sigstore services (build/cosign/signing-config-private.json). Source: BUILD.md.
Done in the code and in the charts, or documented for the provider.
| Requirement | SecNumCloud 3.2 | State | Evidence | Next step |
|---|---|---|---|---|
| Control of the code, no dependency on a non-European vendor | § 19 | Done | Open source Go rewrite of Keystone, Nova, Neutron, Cinder, Glance, Manila, Barbican… (openkeel-*); no telemetry, no outbound call to a third party | Rebuild the images in a European CI |
| Logging of API actions | ch. 12 | Done | A CADF event per call on every API (internal/audit), Keystone identity events (internal/notify), counters openkeel_audit_events_{sent,dropped,failed}_total | Add kube-apiserver and the Talos API to the trail |
| Retention and integrity of the logs | ch. 12 | Done | Documented in openkeel-chart/docs/audit-trail.md: WORM archive (object lock, compliance mode), 12 months with 3 online (Loki 400 d), NTP on the Talos nodes, alerts on losses, SIEM rules | Prove it on a real platform (provider) |
| Access control of the APIs | ch. 9 | Done | OpenStack RBAC policies (admin, member, reader, service, project and system scopes) enforced by every service; 403 refusals as in OpenStack, covered by the conformance tests | Cut over-privileged service accounts |
| Secrets and key management | ch. 10 | Done | Barbican in Go with a PKCS#11 HSM (internal/crypto/p11.go, SoftHSM tests) or Vault / OpenBao; KEK rotation (internal/manage/rotate.go) | ANSSI-qualified HSM in production |
| Isolation of tenant containers | ch. 13 | Done | Zun under Kata Containers by default (RuntimeClass kata): one kernel per tenant container | — |
| Encryption of the network control plane | ch. 10, 13 | Done | OVN Northbound / Southbound in mutual TLS (ssl:) between Neutron, ovn-octavia-provider, FWaaS, VPNaaS, ovn-bgp-agent and OVN central | — |
| Optional APIs can be turned off | ch. 13 | Done | ec2-api can be disabled in the Configurator (component ec2-api of its catalogue) | — |
| Multi-factor authentication | ch. 9 | Done | Keystone: TOTP method (internal/keystone/totp.go) and per-user MFA rules (options.multi_factor_auth_rules, internal/api/mfa_test.go) | OIDC federation |
| Encryption of database flows | ch. 10 | Done | MariaDB with TLS required (infrastructure.mariadb.tls.required: true), the MariaDB operator's CA verified by every service (global.tls.trustedCAs, passed by okadm to every release), tls=skip-verify refused; applied and verified on the lab (require_secure_transport ON) | Check Galera replication in TLS on a three-node cluster (the lab has one node) |
| TLS suites of the listeners | ch. 10 | Done | internal/tlsx in all 16 services (a copy of Keystone's): TLS 1.2 minimum, ECDHE with AES-GCM or ChaCha20 only (ANSSI TLS guide), certificate re-read on renewal; RabbitMQ limited to TLS 1.2/1.3 and AEAD suites | — |
| Smaller attack surface: no unused data service | ch. 13 | Done | Memcached and Redis removed: no component read them; okadm removes them from existing installations (internal/deploy/retired.go) | — |
| Encryption of every internal flow | ch. 10 | Done | global.tls.internal: true by default: internal cert-manager CA (openkeel-ca), one certificate per chart (ECDSA P-256, 90 days); RabbitMQ over AMQPS only; https:// internal URLs and internal catalogue; Ingress to verified HTTPS backends (Traefik ServersTransport, nginx annotations); okadm step rabbitmq-trust; status reports of ovn-octavia-provider to a dedicated TLS listener of Neutron (openkeel-neutron-lbaas:9878, off the admin port). Verified on the lab on 2026-11-08: 18 listeners in HTTPS with a verified certificate, plain HTTP refused, AMQP connections in TLS 1.3 | Network capture: no application flow in clear outside :9090 |
| Integrity and traceability of the OpenKeel images | ch. 14 | Done | Every image built with --sbom=true --provenance=mode=max (ATTEST=1, default): an SPDX SBOM per platform (Debian packages of the distroless base, every Go module) and the SLSA provenance in the image index; make sbom exports them into dist/sbom, with the SBOM of each okadm binary; make sign signs each index by digest with cosign, which covers its attestations (build/sbom.sh, BUILD.md) | Enforce the signatures at admission |
| Third-party images on a controlled registry, with an SBOM | ch. 14 | Done | make mirror-prereqs copies the images of the prerequisites (cert-manager, MariaDB and RabbitMQ operators, MariaDB, RabbitMQ, Traefik: 14 images) registry to registry, every platform, from okadm's release manifest; containerd or Talos redirect each upstream registry to the mirror; MIRROR_SBOM=1 exports an SBOM per copy, attaches one with cosign attest where the publisher has none, and signs every copy with the OpenKeel key; OpenKeel images and the Ironic images, pinned by digest, are pulled through global.imageRegistry | Mirror the images KubeVirt and CDI derive at run time |
Chapter numbers orient the reading; they are to be checked against the published framework before the compliance matrix is built. Source: openkeel-docs/SECNUMCLOUD-STATUS.md.
| Requirement | SecNumCloud 3.2 | State | Evidence | Next step |
|---|---|---|---|---|
| Uniform TLS suites | ch. 10 | In progress | Services (tlsx) and RabbitMQ aligned; the public side of the ingress controllers is left | ANSSI TLS profile on the public entry points of the Ingress |
| Consistent charts | — | In progress | Name clash of the svc.volumes helper between sub-charts (mounting the trusted CAs) | Prefix the helpers per chart |
| Images built and controlled by the provider | ch. 14 | In progress | make release builds every image multi-arch from the workspace (rootless distroless, UID 65532, no shell) with its SBOM, provenance and signature; the default signing config uses none of the public Sigstore services (build/cosign/); Ironic still runs upstream Kolla (Python) images, mirrored by digest | Run make release in a European CI; replace the Kolla images |
| Vulnerability watch on the images | ch. 14 | In progress | make vuln (govulncheck, go mod verify) on every Go module; the SBOMs of the OpenKeel and third-party images can be scanned without pulling them again (grype, trivy sbom) | Scan the SBOMs at each release and periodically for new CVEs |
| Requirement | SecNumCloud 3.2 | State | Evidence | Next step |
|---|---|---|---|---|
| Administrator MFA through an IdP | ch. 9 | To do | Local TOTP only | OIDC federation in Keystone (European IdP, MFA carried by the IdP), mapped to roles |
| MFA for Kubernetes administrators | ch. 9 | To do | Access by kubeconfig with a client certificate (okadm access) | OIDC and MFA to the kube-apiserver, named Kubernetes roles, no permanent cluster-admin |
| Authenticated Configurator | ch. 9 | To do | UI without login; its ClusterRole patches nodes and reads every log (deploy/kustomize/base/rbac.yaml) | OIDC authentication, a smaller ClusterRole, access from the administration IS only |
| Minimal service accounts | ch. 9 | To do | admin role for ec2-api (all_tenants), Masakari, Zun (binding:host_id), Skyline and neutron-vpnaas; openstack-exporter with the admin password | Dedicated roles and targeted policy rules per service; a read-only exporter (system reader) |
| Requirement | SecNumCloud 3.2 | State | Evidence | Next step |
|---|---|---|---|---|
| A key per tenant for volumes | ch. 10 | To do | Cinder records the fixed key 00000000-0000-0000-0000-000000000000 and leaves encryption to the StorageClass | Link Cinder to Barbican: one key per encrypted volume, in the tenant's project |
| Disk encryption | ch. 10 | To do | — | Longhorn LUKS per volume; encryption of MariaDB, Glance and Swift |
| Erasure at contract end | ch. 19 | To do | — | Crypto-shredding: destroy the project's Barbican keys, with a traced procedure |
| No obsolete algorithm | ch. 10 | To do | EC2 v0/v1 signatures in HMAC-SHA1 accepted by Keystone (internal/keystone/ec2sign.go) | An option to accept only v2 (SHA-256) and v4, the old ones off by default in production |
| Qualified HSM | ch. 10 | To do | Generic PKCS#11 tested on SoftHSM | Validate with an ANSSI-qualified HSM |
| Requirement | SecNumCloud 3.2 | State | Evidence | Next step |
|---|---|---|---|---|
| Signatures enforced at admission | ch. 14 | To do | Images signed and attested, but the cluster runs any image | Kyverno verifyImages or the Sigstore policy-controller with cosign.pub, on OpenKeel's and the operators' images alike |
| Requirement | SecNumCloud 3.2 | State | Evidence | Next step |
|---|---|---|---|---|
| Separate administration IS | ch. 9, 13; PA-022 | To do | A written proposal: zones Z1, Z2 and Z3 (openkeel-docs/SECNUMCLOUD-ADMIN-SI.md) | Administration network, bastion, administration workstations (provider) |
| Control plane separated from the data plane | ch. 13 | To do | One Talos cluster carries the APIs and the tenant workloads | Step 1: single-cluster hardening, centralised Nova and Zun agents (no DSN on the hypervisors); target: separate control and data clusters |
| Logging of platform administration | ch. 12 | To do | Only the OpenStack APIs are traced | Audit policy of the kube-apiserver, logs of the Talos API, the bastion and the BMCs, archived like the CADF trail |
| Encrypted admin ports | ch. 10 | To do | Health and metrics on :9090 in plain HTTP, inside the cluster; the status reports of ovn-octavia-provider no longer go there: Neutron serves them on a dedicated TLS listener | TLS (or Prometheus mTLS) on :9090, or a NetworkPolicy that lets only Prometheus in |
| No non-European remote support | § 19.6 | To do | Remote support of the storage arrays (Pure1, vendor remote access) not turned off by OpenKeel | Document and check that it is off in the production install guide |
| Erlang distribution of RabbitMQ | ch. 10 | To do | Traffic between the RabbitMQ nodes (port 25672) not encrypted, inside the cluster | TLS for the Erlang distribution (ssl_dist), which the operator does not manage |
RGW gateway (--ceph-s3) | ch. 10 | To do | RGW reaches Keystone in verified HTTPS (caBundleRef), but serves S3 and Swift in plain HTTP on port 80 inside the cluster | RGW's secure port with a certificate of the internal CA |
| okadm calls to the APIs | ch. 10 | To do | Through the Kubernetes API server's service proxy in https:: encrypted, the Pods' certificates not verified | Call through the Ingress, or verify on the client side |
The OpenKeel APIs are part of the service sold to tenants: they are not the administration IS. The proposal therefore separates three zones, and the administration interfaces of Z2 and Z3 (kube-apiserver, Talos API, BMC, etcd, admin ports) are reachable from Z1 only.
| Zone | Content | Who gets in |
|---|---|---|
| Z1, administration IS | Administration workstations, bastion, administrators' IdP (MFA), okadm runner and Git repository of the values, Configurator, log collection and storage (Loki, SIEM, WORM bucket), signed registry mirror | Administrators only, from their workstations |
| Z2, control plane of the service | OpenKeel APIs, conductors, schedulers, MariaDB, RabbitMQ, Barbican, public Ingress | Tenants (public APIs through the Ingress); administrators through Z1 |
| Z3, data plane | Hypervisors (KubeVirt), Zun nodes (Kata), storage (Longhorn), network gateways (OVN gateway, BGP) | Tenants (their VMs and containers); administrators through Z1 |
Recommendation of the proposal: an administration network and a hardened single cluster now, in every production deployment; centralised Nova and Zun agents as the first development; separate control and data clusters as the target for a qualified offer. Nothing of it is implemented yet.
Finish TLS on every internal flow, then check it with a network capture.
OIDC and MFA for administrators, encryption at rest with a key per tenant.
Images built in a European CI, signatures enforced at admission, the administration IS and the separation of the planes.
The requirement matrix, an internal review, then a pre-audit by a qualified auditor.
Most of the framework concerns the provider who runs the service. OpenKeel does not replace it, but it must not stand in the way, and it supplies part of the evidence.
Security policy, roles, clearances and training of the staff. OpenKeel provides named roles and the audit trail of their actions.
Data centres, access control to the rooms and the hardware. OpenKeel runs on the provider's own servers, in France and in Europe.
Changes, backups, vulnerability and capacity management. okadm plans, installs and upgrades one component at a time; Grafana shows the state of every service.
Detection, handling and notification of incidents. The CADF trail, Loki and the Prometheus alerts give the facts.
§ 19.6: ownership, location of data and support in the European Union. OpenKeel is open source, with no telemetry and no outbound call.
Configurations, policies and logs gathered in the compliance matrix, versioned with the code.
| Step | What | Outcome |
|---|---|---|
| Requirement matrix | SecNumCloud 3.2 chapter by chapter: owner (OpenKeel or provider), mechanism, evidence | Compliance matrix versioned with the code |
| Internal review | Each piece of evidence checked on a production-mode install | Review report, open gaps tracked |
| Pre-audit | Qualified auditor, on a full pilot platform | Pre-audit report and treatment plan |
| PASSI penetration test | Public APIs, VM and Kata escape to the control plane, administration IS | Report, fixes and retest |
| CSPN (optional) | Critical components: Keystone, Barbican, Kata and KubeVirt isolation | First-level certification of the chosen components |