Red Hat OpenShift Container Platform is Kubernetes with its own identity, admission and audit layers, so a cluster hardened only with generic Kubernetes advice still leaves OpenShift-specific gaps such as the kubeadmin account, broad security context constraint grants and long-lived service account tokens carried over from older releases. This guide covers the controls that differ from upstream Kubernetes: the built-in OAuth server and identity providers, cluster-admin and kubeadmin, security context constraints (SCCs) and their interaction with pod security admission, service account tokens, API audit profiles and etcd encryption. It is written for platform engineers, cluster administrators and security teams running self-managed OpenShift 4. Facts come from Red Hat's OpenShift Container Platform 4.21 documentation, read on 8 November 2026; defaults change between minor releases, so check the documentation for your version. For the upstream baseline, see the Kubernetes Security Guide.
This is an independent guide from NHI Mgmt Group, based on Red Hat's public documentation as of November 2026. It is not sponsored or reviewed by Red Hat. Product features change, so confirm settings against Red Hat's current documentation.
Key takeaways
- Remove kubeadmin, but in the right order. The installer-created kubeadmin user has cluster-admin and is treated as root; delete its secret only after an identity provider works and a named user holds cluster-admin, because the deletion cannot be undone.
- Never edit default SCCs. Red Hat warns that customised default SCCs can break platform pods and are reset during some upgrades; create your own SCCs and grant them to specific service accounts.
- Treat privileged, hostaccess, hostmount-anyuid and hostnetwork grants as privileged access. Each gives host-level reach, and a hostnetwork workload on a control plane node is effectively root on the cluster.
- Hunt legacy tokens after upgrades. Since 4.16 OpenShift no longer auto-creates long-lived service account token secrets, but existing ones survive upgrades and keep working until deleted.
- Raise the audit profile and encrypt etcd. The Default audit profile logs metadata only, and etcd encryption is a setting you turn on; both are one-resource changes with large detection and data-protection value.
How identity and access work in OpenShift
OpenShift adds a built-in OAuth server to the control plane. Users do not authenticate to the Kubernetes API with their identity provider credentials directly: they obtain an OpenShift OAuth access token, and the OAuth server uses the configured identity provider to decide who they are, maps that identity to an OpenShift user and issues the token. Service accounts and other workloads authenticate with Kubernetes service account tokens. Authorisation for both is standard Kubernetes RBAC plus OpenShift's own roles.
Identity providers
| Identity provider type | How it validates users | Security notes |
|---|---|---|
| htpasswd | Flat file of user names and password hashes stored as a secret | No MFA, no central offboarding; acceptable for break-glass or labs only |
| Keystone | OpenStack Keystone v3 server | Inherits Keystone's controls |
| LDAP | LDAPv3 simple bind | Use LDAPS; protect the bind credential; no MFA at the cluster |
| Basic authentication | Remote endpoint validates credentials | Generic integration; strength depends on the backend |
| Request header | Trusts a header such as X-Remote-User set by an authenticating proxy | Only safe when the proxy's client certificate and network path are tightly controlled |
| GitHub or GitHub Enterprise, GitLab, Google | OAuth sign-in against the provider | Restrict to your organisation, group or hosted domain |
| OpenID Connect | Any OIDC provider (for example the corporate IdP) | Preferred route to enterprise SSO, MFA and conditional access |
- Default OAuth clients: OpenShift creates
openshift-browser-client(tokens via/oauth/token/request),openshift-challenging-client(WWW-Authenticate challenges) andopenshift-cli-client(authorisation code grant through a local HTTP server). All token requests go through/oauth/authorize. Basic authentication challenges are only sent when anX-CSRF-Tokenheader is present, to protect browser clients from CSRF. - Token lifetime: OAuth access tokens are valid for 24 hours (86400 seconds) by default. Set
spec.tokenConfig.accessTokenMaxAgeSecondson the clusterOAuthresource to change it. Shorter lifetimes reduce the value of a stolen token copied from a kubeconfig. - Inactivity timeout: no inactivity timeout is set by default. Set
accessTokenInactivityTimeoutSecondson anOAuthClient(for exampleconsole), minimum 300 seconds; the client value overrides the server-wide value. - Unauthenticated access: since 4.17, unauthenticated groups have no default access to cluster roles, but clusters upgraded from earlier versions keep the older bindings. Review cluster role bindings for
system:unauthenticatedon upgraded clusters.
Admin roles and privileged access
| Privileged identity or grant | What it can do | Control |
|---|---|---|
kubeadmin | Created at install, has cluster-admin, treated as root; password printed in installer output and stored in auth/ with the installer kubeconfig | Configure an IdP, grant cluster-admin to a named user or group, test it, then delete the kubeadmin secret in kube-system |
| Installer kubeconfig (system:admin certificate) | Certificate-based cluster-admin that does not depend on the OAuth server | Keep offline in a vault as break-glass; log and alert on its use |
cluster-admin role bindings | Full control of every project and the cluster | Bind to groups from the IdP, not individual users; review quarterly |
use on privileged SCCs | Lets pods run privileged, mount the host or join host namespaces | Grant only to named service accounts in named namespaces |
Impersonation (impersonate verb) | Act as another user, group or service account | Restrict to platform tooling; audit impersonatedUser |
Access to openshift-* projects | These host critical control plane and infrastructure components | No application workloads or broad edit rights there |
- Order of kubeadmin removal: Red Hat states that if you remove kubeadmin before another user has cluster-admin, the cluster must be reinstalled. Prove a named admin can sign in through the IdP and run an admin action first.
- Break-glass: the IdP is a single point of failure for human admin access. Keep the installer kubeconfig or a dedicated htpasswd break-glass account in a vault with dual control. See the Break-Glass Emergency Access Guide.
- Projects and RBAC: projects are namespaces with OpenShift metadata, and project admins can grant roles within them. Review who holds
adminon each project. See the Kubernetes RBAC Guide.
Security context constraints and pod security admission
SCCs are OpenShift's admission control for pod privileges. An SCC decides whether a pod may run privileged containers (allowPrivilegedContainer), escalate privileges (allowPrivilegeEscalation), request capabilities, mount host directories, use host namespaces and networking, which UID, SELinux context, FSGroup and supplemental groups it gets, which volume types and seccomp profiles it may use, and whether the root file system must be read-only.
| Default SCC | What it allows | Risk level |
|---|---|---|
restricted-v3 | Like restricted-v2, plus pods must run in a Linux user namespace (hostUsers: false); Red Hat describes it as the most restrictive default SCC on new installations | Lowest |
restricted-v2 | Drops ALL capabilities (NET_BIND_SERVICE can be added), seccomp runtime/default, no privilege escalation, namespace-allocated UID and SELinux context; default for authenticated users | Low |
restricted | Older restricted SCC; available to all authenticated users only on clusters upgraded from 4.10 or earlier | Low to medium |
nonroot, nonroot-v2 | Any non-root UID | Medium |
anyuid | Restricted features but any UID and GID, including 0 | Medium to high |
hostnetwork, hostnetwork-v2 | Host networking and host ports | High; on control plane nodes effectively root |
hostaccess | All host namespaces, file systems and PIDs | High |
hostmount-anyuid, node-exporter | Host file system access as any UID including 0 | High |
privileged | Everything: privileged pods, host directories, any user, any capability, host IPC and PID | Highest; cluster administration only |
- Do not modify default SCCs: create a custom SCC (often a copy of restricted-v2 with one change) and grant
useon it to a specific service account. Default SCCs can be reset during upgrades. - Selection is by priority and permission: setting
privileged: truein a pod spec does not by itself pick the privileged SCC; the highest-priority SCC that allows the request and that the user or service account may use is chosen. Unexpected SCC selection is visible in the pod'sopenshift.io/sccannotation. - Do not set
openshift.io/run-levelon any namespace: it is reserved for internal components, and Red Hat warns that SCCs are not applied in namespaces carrying it. - Pod security admission runs alongside SCCs: globally the
privilegedprofile is enforced andrestrictedis used for warnings and audits. Thewarnandauditlabels are synchronised automatically from the SCCs that service accounts in each namespace may use. Setpod-security.kubernetes.io/enforce=restrictedon application namespaces once warnings are clean.default,kube-publicandkube-systemare always privileged. See the Kubernetes Admission Control Guide.
Integrations, API tokens and service accounts
CI/CD pipelines, GitOps controllers, monitoring agents and operators all act through service accounts. These are the cluster's non-human identities, and they usually hold more rights than any human user.
- Legacy long-lived tokens: before 4.16 OpenShift generated a long-lived API token secret for every service account. From 4.16 it no longer does, but existing secrets are not deleted on upgrade and keep working. Inventory secrets of type
kubernetes.io/service-account-token, find which are still used (audit loguser.usernameofsystem:serviceaccount:*with legacy token authentication) and delete the unused ones. See the guide to rotating Kubernetes service account tokens. - Prefer short-lived projected tokens: workloads should use the projected, audience-bound tokens Kubernetes mounts by default. External systems such as CI runners should use token requests with short expiry or workload identity federation instead of pasted static tokens. See the Kubernetes Service Account Token Guide.
- Image pull secrets: OpenShift still creates an image pull secret per service account when the integrated registry is enabled. Treat them as credentials in reviews.
- OAuth tokens in kubeconfigs: tokens from
oc loginsit in plain text in~/.kube/configon laptops and CI runners. ShortaccessTokenMaxAgeSecondsand inactivity timeouts limit the damage when one leaks. - Operators: operators from catalogues often request cluster-wide RBAC and sometimes custom SCCs. Review the permissions in the operator's ClusterServiceVersion before installing, and remove operators you no longer use.
- Secrets at rest: secrets are base64 in etcd unless etcd encryption is on. For external secret stores, see the Kubernetes Secrets Security Guide.
Logging and detection
OpenShift audits requests to the Kubernetes API server, OpenShift API server, OpenShift OAuth API server and OAuth server. The policy is set with spec.audit.profile on the APIServer resource named cluster, and custom rules can apply a different profile per group.
| Audit profile | What is logged | When to use |
|---|---|---|
Default | Metadata for read and write requests; no request bodies except OAuth access token requests | Minimum for any cluster |
WriteRequestBodies | Metadata plus bodies of create, update, patch, delete and deletecollection requests | Recommended for security monitoring: shows what an RBAC or SCC change actually set |
AllRequestBodies | Metadata plus bodies of reads and writes | Short investigations; highest overhead and may capture secret contents |
None | Nothing, including OAuth token requests; custom rules ignored | Never in production; Red Hat warns against it |
Audit events carry user, impersonatedUser, sourceIPs, userAgent (client-supplied, not trustworthy), verb, objectRef and responseStatus. Forward them off the nodes to a SIEM. Detections worth building:
| Detection | Audit signal | ATT&CK |
|---|---|---|
| kubeadmin sign-in after it should be gone | OAuth or API requests with user.username kube:admin | T1078.001 Default Accounts |
| Privileged SCC granted | create or patch of RoleBinding or ClusterRoleBinding referencing system:openshift:scc:privileged, or edits to SCC users and groups | T1611 Escape to Host |
| New cluster-admin binding | create ClusterRoleBinding with roleRef cluster-admin | T1078.001 Default Accounts (when an installer account is used) |
| Exec into pods in openshift- projects | create on pods/exec in openshift-* namespaces | T1609 Container Administration Command |
| Secret enumeration by a service account | list on secrets cluster-wide from system:serviceaccount:* | T1552.007 Container API |
| Unexpected privileged workload | pod created with host namespaces or privileged SCC annotation outside allowed namespaces | T1610 Deploy Container |
| Broad discovery from a new identity | high-volume list across resource types from one user | T1613 Container and Resource Discovery |
For query patterns, see the Kubernetes Audit Log Detection Guide.
Hardening baseline
- Identity first: configure an OpenID Connect or LDAPS identity provider with MFA enforced at the IdP, map admin groups to
cluster-admin, test, then remove kubeadmin. - Vault the installer kubeconfig as break-glass with dual control and an alert on any use.
- Token lifetime: lower
accessTokenMaxAgeSecondsto a working day or less and setaccessTokenInactivityTimeoutSecondson the console and CLI clients. - Audit: set the audit profile to
WriteRequestBodies(test overhead in a non-production cluster first; roll back by settingDefault), and forward logs to the SIEM. - etcd encryption: enable it with AES-GCM or AES-CBC. It encrypts secrets, config maps, routes and OAuth access and authorize tokens (values only, not names). Keys rotate every 7 days and up to 10 old keys are kept; store the etcd backup's static resources file, which holds the keys, separately from the snapshot.
- SCC review: list who may use each non-restricted SCC; replace grants of default high-risk SCCs with narrow custom SCCs.
- Pod security admission: move application namespaces to
enforce=restrictedonce synchronisedwarnlabels show no violations. - Legacy tokens and unauthenticated bindings: on upgraded clusters, delete unused long-lived service account token secrets and remove
system:unauthenticatedbindings that are not needed. - Network: apply default-deny NetworkPolicies per project and allow only required flows. See the Container Security Guide.
- Compliance scanning: Red Hat's Compliance Operator can scan cluster and node configuration against benchmark profiles; run it on a schedule and track drift.
Framework mapping
| OpenShift control | NIST SP 800-53 Rev. 5 | NIST CSF 2.0 |
|---|---|---|
| IdP integration, kubeadmin removal | IA-2, AC-2 | PR.AA-05 |
| RBAC and SCC least privilege | AC-3, AC-6 | PR.AA-05 |
| Audit profile and forwarding | AU-2, AU-12 | DE.CM-03 |
| etcd encryption | SC-28 | PR.DS-01 |
| Compliance Operator baseline | CM-6 | PR.PS-01 |
Common misconfigurations
- kubeadmin still present months after install: a shared root password from installer output often sits in a ticket or chat thread. Remove it once SSO works.
- Granting
anyuidorprivilegedto fix one image: teams add the SCC to a project's default service account so a vendor image runs as root, which then applies to every pod using that account. Use a dedicated service account and a narrow custom SCC, or rebuild the image to run as non-root. - Editing default SCCs: changes break platform pods or silently disappear at the next upgrade.
- Upgraded clusters keep old defaults: legacy long-lived service account tokens, the old
restrictedSCC for all authenticated users, and unauthenticated role bindings all survive upgrades from older releases. - Audit logs left on the nodes at Default: without request bodies and central retention, investigators cannot see what an attacker changed in an RoleBinding or SCC.
- etcd backups without encryption or with keys stored beside them: an exposed backup then yields every secret and OAuth token in the cluster.
Practitioner checklist
- Confirm an OIDC or LDAPS identity provider with IdP-side MFA is the only route for human admins.
- Remove kubeadmin after a named cluster-admin has been tested, and vault the installer kubeconfig as break-glass.
- Set OAuth access token lifetime and inactivity timeouts to match your session policy.
- List every subject that can use privileged, hostaccess, hostmount-anyuid, hostnetwork and anyuid SCCs, and justify each.
- Replace edits to default SCCs with custom SCCs bound to specific service accounts.
- Enforce the restricted pod security profile on application namespaces.
- Find and delete unused long-lived service account token secrets on clusters upgraded from before 4.16.
- Set the audit profile to WriteRequestBodies, forward logs to the SIEM and deploy the detections above.
- Enable etcd encryption and store backup key files separately from snapshots.
- Schedule Compliance Operator scans and review drift monthly.
Standards and references
- Red Hat: Managing security context constraints (OpenShift Container Platform 4.21)
- Red Hat: OpenShift documentation source, Remove the kubeadmin user
- Red Hat: OpenShift documentation source, Configure the internal OAuth server's token duration
- Red Hat: OpenShift documentation source, About audit log policy profiles
- Red Hat: OpenShift documentation source, etcd encryption
- Red Hat: OpenShift documentation source, About pod security admission synchronization
- NIST: SP 800-53 Rev. 5
- MITRE ATT&CK: Escape to Host
Related NHI Mgmt Group resources: Kubernetes Security Guide · Kubernetes NHI Security Guide · Kubernetes RBAC Guide · Kubernetes Audit Log Detection Guide