Admission Controller
Overview
Section titled “Overview”The QHx Admission Controller automatically applies Multi-Level Security (MLS) labels to Kubernetes resources based on the identity of the principal creating them. This ensures consistent classification tagging across the cluster without requiring manual label management.
The admission controller runs as part of qhx-manager and enforces policy through Kubernetes mutating and validating webhooks.
How It Works
Section titled “How It Works”When a principal creates or updates a Kubernetes resource:
- Identity Extraction: Extract username, groups, and attributes from the authentication context
- Policy Evaluation: Map groups to MLS labels using configured policy
- Label Application: Apply classification, compartment, and releasability labels
- Validation: Reject operations that violate MLS policy
Labels are derived from the principal’s Kubernetes groups and cannot be arbitrarily changed by users.
MLS Labels
Section titled “MLS Labels”QHx applies three types of labels:
Classification Level
Section titled “Classification Level”Format: mls.qhx.dev/level
Represents the classification level of the resource. Exactly one classification level is assigned per resource.
Example values:
us:u(Unclassified)us:c(Confidential)us:s(Secret)us:ts(Top Secret)
Compartment
Section titled “Compartment”Format: mls.qhx.dev/compartment
Represents a compartment or special access program. Zero or one compartment is assigned per resource.
Example values:
quantumtempestdragon
Releasability
Section titled “Releasability”Format: mls.qhx.dev/releasability
Comma-separated list of releasability namespaces indicating which foreign partners can access the data.
Example values:
us,uk,au(FVEY)us,nato- “ (empty - no foreign release)
Group Mapping
Section titled “Group Mapping”The admission controller maps Kubernetes groups to MLS labels through QHxClusterPolicy configuration.
Example Configuration
Section titled “Example Configuration”apiVersion: qhx.dev/v1kind: QHxClusterPolicymetadata: name: qhx-cluster-policyspec: groupMapping: classification: - group: "mls:classification:unclassified" level: "us:u" - group: "mls:classification:secret" level: "us:s" - group: "mls:classification:topsecret" level: "us:ts"
compartment: - group: "mls:compartment:quantum" value: "quantum" - group: "mls:compartment:tempest" value: "tempest"
releasability: - group: "mls:releasability:us" value: "us" - group: "mls:releasability:uk" value: "uk" - group: "mls:releasability:au" value: "au" - group: "mls:releasability:nato" value: "nato"Principal Identity Example
Section titled “Principal Identity Example”A principal with these groups:
mls:classification:secretmls:releasability:usmls:releasability:ukmls:releasability:aumls:compartment:quantumCreates resources with these labels:
metadata: labels: mls.qhx.dev/level: "us:s" mls.qhx.dev/releasability: "us,uk,au" mls.qhx.dev/compartment: "quantum"Releasability Control
Section titled “Releasability Control”Releasability labels have special handling to allow users to exercise a subset of their authorized releasabilities.
Bounding Set
Section titled “Bounding Set”The principal’s groups define a bounding set of releasabilities. The principal can create resources with any subset of this bounding set.
Example:
Principal has groups: mls:releasability:us, mls:releasability:uk, mls:releasability:au
Valid releasability values the principal can specify:
us,uk,au(all authorized)us,uk(subset)us(single value)- “ (empty - no foreign release)
Invalid values:
us,jp(includes unauthorizedjp)nato(not in bounding set)
Default Releasability
Section titled “Default Releasability”Configure default releasability in QHxClusterPolicy:
spec: defaultReleasability: ["us", "uk"]If a principal does not explicitly specify releasability, the default is applied in addition to the principal’s bounding set.
Example with default ["us", "uk"]:
- Principal has:
mls:releasability:au - Resource created with no explicit releasability
- Result:
mls.qhx.dev/releasability: "us,uk,au"
Set to empty list to default to no releasability:
spec: defaultReleasability: []Autolabelling Mode
Section titled “Autolabelling Mode”QHxClusterPolicy controls whether labels are applied automatically or required explicitly:
Automatic Labeling (Default)
Section titled “Automatic Labeling (Default)”spec: autolabelling: trueThe admission controller automatically adds required MLS labels to resources. Users do not specify labels manually.
Explicit Labeling
Section titled “Explicit Labeling”spec: autolabelling: falseUsers must explicitly apply correct MLS labels to resources. The admission controller validates labels but does not add them automatically.
If labels are missing or incorrect, resource creation is rejected with an error message describing requirements.
Use explicit labeling when:
- Operators must consciously acknowledge classification levels
- Compliance requires explicit classification decisions
- Additional approval workflow is required before resource creation
Label Immutability
Section titled “Label Immutability”MLS labels cannot be changed after resource creation, except:
- Releasability can be reduced (subset of original value)
- Status field updates by controllers are allowed
- Some annotation changes are permitted
Attempts to modify classification level or compartment are rejected.
To change MLS labels, delete and recreate the resource.
Controlled Resource Types
Section titled “Controlled Resource Types”The admission controller manages labels for these resource types:
- ConfigMap
- CronJob
- DaemonSet
- Deployment
- Job
- Namespace
- PersistentVolume
- Pod
- ReplicaSet
- Secret
- Service
- ServiceAccount
- StatefulSet
Other resource types are not labeled or controlled.
Sealed Policy
Section titled “Sealed Policy”Seal a QHxClusterPolicy to make it immutable:
apiVersion: qhx.dev/v1kind: QHxClusterPolicymetadata: name: qhx-cluster-policy annotations: qhx.dev/sealed: "true"spec: # ... policy configurationOnce sealed:
- The QHxClusterPolicy cannot be modified via normal Kubernetes API operations
- Mutating and validating webhook configurations cannot be deleted
- Policy can only be updated via signed resources (see Signed Resources guide)
Sealing enables permanent policy enforcement that cannot be circumvented through the Kubernetes API.
Warning: Seal policy only after thorough testing. Unsealing requires direct access to cluster control plane nodes.
Policy Validation
Section titled “Policy Validation”Validate policy configuration before applying:
# Check current policykubectl get qhxclusterpolicy qhx-cluster-policy -o yaml
# Test policy by creating a test resourcekubectl create configmap test-mls --dry-run=server -o yamlCheck admission controller logs:
kubectl logs -n qhx-system -l app=qhx-manager | grep admissionTroubleshooting
Section titled “Troubleshooting”Labels Not Applied
Section titled “Labels Not Applied”Check if admission controller webhook is active:
kubectl get mutatingwebhookconfigurations | grep qhxkubectl get validatingwebhookconfigurations | grep qhxVerify qhx-manager is running:
kubectl get pods -n qhx-system -l app=qhx-managerCheck admission controller logs:
kubectl logs -n qhx-system -l app=qhx-manager | tail -50Resource Creation Rejected
Section titled “Resource Creation Rejected”Common rejection reasons:
Missing Group Mapping:
Error: Principal has group "mls:classification:secret" but no mapping exists in QHxClusterPolicySolution: Add group mapping to QHxClusterPolicy.
Invalid Releasability:
Error: Releasability "us,jp" includes unauthorized values. Principal's bounding set: "us,uk"Solution: Specify only authorized releasabilities.
Policy Validation Failed:
Error: Cannot modify sealed resourceSolution: Use signed resource to update sealed resources.
Incorrect Labels
Section titled “Incorrect Labels”Verify principal’s groups:
kubectl auth whoamiCheck group mapping in policy:
kubectl get qhxclusterpolicy qhx-cluster-policy -o yaml | grep -A 20 groupMappingLabel Modification Rejected
Section titled “Label Modification Rejected”MLS labels are immutable by design. To change labels:
# Save resource definitionkubectl get deployment my-app -o yaml > my-app.yaml
# Delete resourcekubectl delete deployment my-app
# Edit labels in YAMLvim my-app.yaml
# Recreate with new labelskubectl apply -f my-app.yamlIntegration with Network Isolation
Section titled “Integration with Network Isolation”MLS labels applied by the admission controller are used by QHx Manager to automatically generate NetworkPolicies. See the Network Isolation guide for details.
Resources with identical MLS labels can communicate freely. Resources with different MLS labels are isolated by default.
Example Workflow
Section titled “Example Workflow”1. Configure Policy
Section titled “1. Configure Policy”apiVersion: qhx.dev/v1kind: QHxClusterPolicymetadata: name: qhx-cluster-policyspec: autolabelling: true defaultReleasability: [] groupMapping: classification: - group: "mls:classification:secret" level: "us:s" compartment: - group: "mls:compartment:quantum" value: "quantum" releasability: - group: "mls:releasability:us" value: "us" - group: "mls:releasability:uk" value: "uk"Apply policy:
kubectl apply -f qhx-cluster-policy.yaml2. Configure Authentication Provider
Section titled “2. Configure Authentication Provider”Ensure authentication provider issues appropriate groups. Example for OIDC:
apiVersion: v1kind: Configusers:- name: operator@example.mil user: auth-provider: config: extra-scopes: groups # ... other config3. Create Resource
Section titled “3. Create Resource”Principal with groups mls:classification:secret, mls:compartment:quantum creates:
apiVersion: v1kind: ConfigMapmetadata: name: sensitive-configdata: key: valueResult:
apiVersion: v1kind: ConfigMapmetadata: name: sensitive-config labels: mls.qhx.dev/level: "us:s" mls.qhx.dev/compartment: "quantum" mls.qhx.dev/releasability: ""data: key: value4. Verify Labels
Section titled “4. Verify Labels”kubectl get configmap sensitive-config -o yaml | grep mls.qhx.devSecurity Considerations
Section titled “Security Considerations”- Authentication provider must issue trustworthy groups
- Group mappings should align with organizational security policy
- Seal policy after deployment to prevent tampering
- Monitor admission controller logs for policy violations
- Restrict RBAC permissions to prevent unauthorized policy changes
- Use signed resources for policy updates in high-security environments