Skip to content

Remove kolla entrypoint pattern, harden SecurityContext - #747

Merged
openshift-merge-bot[bot] merged 1 commit into
openstack-k8s-operators:mainfrom
stuggi:remove-kolla
Aug 19, 2026
Merged

Remove kolla entrypoint pattern, harden SecurityContext#747
openshift-merge-bot[bot] merged 1 commit into
openstack-k8s-operators:mainfrom
stuggi:remove-kolla

Conversation

@stuggi

@stuggi stuggi commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Eliminate kolla_start/kolla_set_configs and the config.json staging pattern. Configs are now mounted directly to final paths via SubPath volume mounts, removing the need for root privilege escalation at container startup.

Key changes:

  • Replace kolla_start with /usr/sbin/httpd -DFOREGROUND
  • Remove kolla_set_configs from bootstrap command
  • Remove all KOLLA_CONFIG_STRATEGY and KOLLA_BOOTSTRAP env vars
  • Delete keystone-api-config.json (no longer needed)
  • Mount configs via SubPath to /etc/keystone/, /etc/httpd/, /etc/my.cnf
  • Add emptyDir volumes for writable paths (/run/httpd, /tmp, /var/log) using lib-common volume.WritableDirVolume/Mount helpers with standardized constants (volume.RunHttpdVolumeName, TmpVolumeName, etc.)
  • Use pod.RestrictiveSecurityContext and RestrictivePodSecurityContext from lib-common for all workloads (deployment, bootstrap, dbsync, cronjob), setting ReadOnlyRootFilesystem, dropping ALL capabilities, and enabling seccomp RuntimeDefault
  • Set AutomountServiceAccountToken=false on all workloads — none need k8s API access (ServiceAccountName is kept for SCC binding)
  • Import KeystoneUID from lib-common modules/serviceuser
  • Override TLS CertMount/KeyMount to /etc/pki/tls/ for Apache
  • Migrate SCC from anyuid to nonroot-v2
  • Update httpd.conf: User/Group keystone, PidFile /run/httpd/httpd.pid
  • Support custom httpd config keys via dynamic SubPath mounts
  • Config Secret DefaultMode set to 0440 (owner-read + group-read, most restrictive — all SubPath mounts are ReadOnly: true anyway)
  • Update functional and kuttl tests

Testing on a cluster surfaced a permission denial starting httpd:

httpd: Syntax error on line 16 of /etc/httpd/conf/httpd.conf:
Could not open configuration file /etc/httpd/conf.d/auth_openidc.conf:
Permission denied

mod_auth_openidc's auth_openidc.conf ships root:apache 0640 and is baked into the container image rather than volume-mounted, so FSGroup does not apply to it. Under the previous kolla/anyuid setup this was never an issue: the httpd master process ran as root and could read any file regardless of group. TCIB never adds the keystone service user to the apache group (uid_gid_manage.sh only ever adds it to "kolla"), so running the whole pod as non-root keystone requires the apache group to be granted explicitly at the pod level via RestrictivePodSecurityContext's new supplementalGroups parameter and lib-common's serviceuser.ApacheGID constant.

Testing further surfaced httpd failing to start with:

(13)Permission denied: AH00091: httpd: could not open error log
file /etc/httpd/logs/error_log.
AH00015: Unable to open logs

/etc/httpd/logs is a symlink to /var/log/httpd (root:root 0700 in the image). httpd.conf only redirected ErrorLog/CustomLog to /dev/stdout inside blocks, so the global/startup error log fell back to Apache's compiled-in default of "logs/error_log" relative to ServerRoot. Fixed by adding a top-level ErrorLog directive, plus a var-log-httpd emptyDir mounted at /var/log/httpd as defense-in-depth for any other RPM-shipped conf.d file that references relative "logs/*" paths.

ErrorLog (both the top-level and per-vhost directives) is sent to /dev/stderr rather than /dev/stdout, following the convention used by the official Apache httpd container image and OpenShift Logging's per-stream labeling, keeping error diagnostics distinguishable from routine access logs (CustomLog stays on /dev/stdout).

Testing also surfaced a keystone WARNING:

keystone.common.fernet_utils [...] key_repository is world readable:
/etc/keystone/fernet-keys

The fernet-keys and credential-keys Secret volumes had no DefaultMode set, so Kubernetes defaulted to 0644 (world-readable), unlike config-data which was already hardened to 0440. Fixed by setting DefaultMode 0440 on both, matching config-data and silencing the warning.

Jira: OSPRH-33504
Jira: OSPRH-33503

Depends-On: openstack-k8s-operators/lib-common#728

@stuggi

stuggi commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

/test keystone-operator-build-deploy-kuttl

@centosinfra-prod-github-app

Copy link
Copy Markdown

This change depends on a change that failed to merge.

Change openstack-k8s-operators/lib-common#728 is needed.

@stuggi
stuggi force-pushed the remove-kolla branch 2 times, most recently from bf39cea to 06b5d4c Compare August 7, 2026 11:47
@stuggi

stuggi commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

/test functional

@stuggi
stuggi force-pushed the remove-kolla branch 2 times, most recently from 486b47c to 7e41b98 Compare August 10, 2026 11:42
@centosinfra-prod-github-app

Copy link
Copy Markdown

Build failed (check pipeline). Post recheck (without leading slash)
to rerun all jobs. Make sure the failure cause has been resolved before
you rerun jobs.

https://gateway-cloud-softwarefactory.apps.ocp.cloud.ci.centos.org/zuul/t/rdoproject.org/buildset/a59ef58ac068415aa3d1d55ab2f1c029

✔️ keystone-openstack-meta-content-provider-master SUCCESS in 1h 36m 07s (non-voting)
keystone-operator-tempest-master FAILURE in 1h 12m 09s (non-voting)
openstack-k8s-operators-content-provider FAILURE in 10m 13s
⚠️ keystone-operator-kuttl SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider (non-voting)
⚠️ keystone-operator-tempest SKIPPED Skipped due to failed job openstack-k8s-operators-content-provider (non-voting)

@centosinfra-prod-github-app

Copy link
Copy Markdown

This change depends on a change that failed to merge.

Changes openstack-k8s-operators/lib-common#732, openstack-k8s-operators/s2i-openstack-containers#46 are needed.

@stuggi

stuggi commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

recheck

@stuggi
stuggi force-pushed the remove-kolla branch 2 times, most recently from 33e5731 to 53ca904 Compare August 12, 2026 15:14
@stuggi

stuggi commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

/test functional

Comment thread internal/controller/keystoneapi_controller.go Outdated
Comment thread internal/keystone/bootstrap.go
Comment thread internal/keystone/deployment.go Outdated
@centosinfra-prod-github-app

Copy link
Copy Markdown

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.
Warning:
Error merging github.com/openstack-k8s-operators/keystone-operator for 747,cf69f4ab9647db07e9559e8319579076c057d7bf

@stuggi

stuggi commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

recheck

@abays abays left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

Eliminate kolla_start/kolla_set_configs and the config.json staging
pattern. Configs are now mounted directly to final paths via SubPath
volume mounts, removing the need for root privilege escalation at
container startup.

Key changes:
- Replace kolla_start with /usr/sbin/httpd -DFOREGROUND
- Remove kolla_set_configs from bootstrap command
- Remove all KOLLA_CONFIG_STRATEGY and KOLLA_BOOTSTRAP env vars
- Delete keystone-api-config.json (no longer needed)
- Mount configs via SubPath to /etc/keystone/, /etc/httpd/, /etc/my.cnf
- Add emptyDir volumes for writable paths (/run/httpd, /tmp, /var/log)
  using lib-common volume.WritableDirVolume/Mount helpers with
  standardized constants (volume.RunHttpdVolumeName, TmpVolumeName, etc.)
- Use pod.RestrictiveSecurityContext and RestrictivePodSecurityContext
  from lib-common for all workloads (deployment, bootstrap, dbsync,
  cronjob), setting ReadOnlyRootFilesystem, dropping ALL capabilities,
  and enabling seccomp RuntimeDefault
- Set AutomountServiceAccountToken=false on all workloads — none need
  k8s API access (ServiceAccountName is kept for SCC binding)
- Import KeystoneUID from lib-common modules/serviceuser
- Override TLS CertMount/KeyMount to /etc/pki/tls/ for Apache
- Migrate SCC from anyuid to nonroot-v2
- Update httpd.conf: User/Group keystone, PidFile /run/httpd/httpd.pid
- Support custom httpd config keys via dynamic SubPath mounts
- Config Secret DefaultMode set to 0440 (owner-read + group-read,
  most restrictive — all SubPath mounts are ReadOnly: true anyway)
- Update functional and kuttl tests

Testing on a cluster surfaced a permission denial starting httpd:

  httpd: Syntax error on line 16 of /etc/httpd/conf/httpd.conf:
  Could not open configuration file /etc/httpd/conf.d/auth_openidc.conf:
  Permission denied

mod_auth_openidc's auth_openidc.conf ships root:apache 0640 and is
baked into the container image rather than volume-mounted, so FSGroup
does not apply to it. Under the previous kolla/anyuid setup this was
never an issue: the httpd master process ran as root and could read
any file regardless of group. TCIB never adds the keystone service
user to the apache group (uid_gid_manage.sh only ever adds it to
"kolla"), so running the whole pod as non-root keystone requires the
apache group to be granted explicitly at the pod level via
RestrictivePodSecurityContext's new supplementalGroups parameter and
lib-common's serviceuser.ApacheGID constant.

Testing further surfaced httpd failing to start with:

  (13)Permission denied: AH00091: httpd: could not open error log
  file /etc/httpd/logs/error_log.
  AH00015: Unable to open logs

/etc/httpd/logs is a symlink to /var/log/httpd (root:root 0700 in the
image). httpd.conf only redirected ErrorLog/CustomLog to /dev/stdout
inside <VirtualHost> blocks, so the global/startup error log fell back
to Apache's compiled-in default of "logs/error_log" relative to
ServerRoot. Fixed by adding a top-level ErrorLog directive, plus a
var-log-httpd emptyDir mounted at /var/log/httpd as defense-in-depth
for any other RPM-shipped conf.d file that references relative
"logs/*" paths.

ErrorLog (both the top-level and per-vhost directives) is sent to
/dev/stderr rather than /dev/stdout, following the convention used by
the official Apache httpd container image and OpenShift Logging's
per-stream labeling, keeping error diagnostics distinguishable from
routine access logs (CustomLog stays on /dev/stdout).

Testing also surfaced a keystone WARNING:

  keystone.common.fernet_utils [...] key_repository is world readable:
  /etc/keystone/fernet-keys

The fernet-keys and credential-keys Secret volumes had no DefaultMode
set, so Kubernetes defaulted to 0644 (world-readable), unlike
config-data which was already hardened to 0440. Fixed by setting
DefaultMode 0440 on both, matching config-data and silencing the
warning.

Jira: OSPRH-33504
Jira: OSPRH-33503
    
Depends-On: openstack-k8s-operators/lib-common#728
    
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Martin Schuppert <mschuppert@redhat.com>

@Deydra71 Deydra71 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

@openshift-ci

openshift-ci Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: abays, Deydra71, stuggi

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [Deydra71,abays,stuggi]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot
openshift-merge-bot Bot merged commit 3fb4181 into openstack-k8s-operators:main Aug 19, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants