Devices

DeviceClass restrictions for Dynamic Resource Allocation claims and templates.

DeviceClass enforcement is configured under spec.rules[].enforce.devices.classes. It controls which classes may be referenced by ResourceClaims and ResourceClaimTemplates in selected Tenant namespaces. DeviceClasses are cluster-scoped resources used by Dynamic Resource Allocation (DRA).

Rules use the shared namespace selection, audiences, conditions, and actions and order. See Reference for a complete Tenant example.

Rule Composition

Actions and order

Each requested DeviceClass is evaluated independently in declaration order. The last matching allow or deny wins for that class. If action is omitted, it defaults to deny.

ActionBehavior
allowCreates an allow-list. A class without a matching allow or deny decision is rejected when an applicable class allow rule exists.
denyRejects matching classes. A later matching allow rule can override the decision.
auditEmits NamespaceRuleAudit Kubernetes events for matches, without granting access or satisfying an allow-list. No admission warnings are added.

Every class reference must pass. This includes every firstAvailable alternative, even when Kubernetes could allocate the first allowed alternative. One forbidden fallback rejects the entire claim or template.

If no class rule applies, these rules add no class restriction. An allow decision does not bypass RBAC, other admission checks, or an existing Tenant-wide DeviceClass restriction.

Admission scope and limits

The checks apply to main-resource creation using resource.k8s.io/v1 or resource.k8s.io/v1beta2:

ResourceClass references checked
ResourceClaimspec.devices.requests[].exactly.deviceClassName and every spec.devices.requests[].firstAvailable[].deviceClassName.
ResourceClaimTemplateThe same fields under spec.spec.devices.requests[].
  • Metadata updates, status updates, and deletion do not reauthorize classes. A resource with no device requests has no class references to evaluate.
  • Namespace selection and policy changes affect subsequent admissions. Existing claims and allocations are not revoked or rewritten.
  • Claims created by controllers are checked against the current profile of the destination namespace. An existing template can therefore stop producing claims after the profile changes. Check Kubernetes events on the Pod when claim creation fails.
  • Class rules validate references; they do not default or replace class names, select an allocation, or grant administrative device access.

Class defaults are configured separately through Device mutations. They fill missing class names; the resulting references still have to pass the enforcement rules below.

Device Classes

Each entry in devices.classes must define exact, exp, or selector. Entries are alternatives: any matching entry matches that enforcement rule. Within an entry, the name criterion and label selector are also alternatives.

FieldMatching behavior
exactMatches one of the supplied DeviceClass names. Names must be valid Kubernetes DNS subdomain names.
expMatches the DeviceClass name using the shared regular-expression matching behavior. Use ^ and $ when the entire name must match.
negateInverts the combined exact/exp name match. It does not invert selector, and requires a name criterion when set to true.
selector.matchLabelsMatches labels on the referenced DeviceClass. All specified labels must match.
selector.matchExpressionsAdds standard Kubernetes label-selector requirements, combined with matchLabels.

An omitted or null selector adds no label criterion. An explicit selector: {} matches every existing DeviceClass, including classes with no labels. Claim labels and namespace labels cannot satisfy a DeviceClass selector. Namespace labels select the profile through namespaceSelector instead.

A class list supports up to 64 entries. An exact list supports up to 64 names, and an exp supports up to 4096 characters. An omitted class list adds no class restriction; an explicit empty list is invalid.

Missing classes and label changes

If any applicable class allow or deny rule uses a selector, every referenced DeviceClass must exist, including classes that also match by name. Missing classes are rejected before rule ordering can grant access. A missing class does not itself cause an audit-only selector rule to deny admission.

Name-only rules match the requested name without requiring an existing DeviceClass. They can authorize a name before its class is created. Kubernetes and the DRA driver must still be able to satisfy the claim. The Tenant-wide setting described below continues to require existing classes.

Selectors use the class’s current labels during admission. Changing class labels affects subsequent admissions, without revoking existing claims or allocations.

Conditions and audiences

Use enforce.conditions to inspect the incoming claim or template through object and admission metadata through request. There is no DeviceClass CEL variable; use selector to match class labels. A false condition skips that enforcement block, including its allow-list contribution.

With no audience, a rule applies to every caller in the selected namespace, including controllers and administrators. An audience restricted to Tenant owners does not cover claims created by Kubernetes controllers on their behalf. Keep mandatory class restrictions free of caller-specific audiences and conditions that would exempt those controllers.

Tenant-wide restrictions

The existing Tenant.spec.deviceClasses setting remains supported. When it is configured alongside namespace rules, each reference must pass both policies. A namespace rule cannot widen the Tenant-wide allow-list. Its current syntax and behavior are documented under Tenant enforcement.

Multi-tenant security

Keep DeviceClass creation, updates, and policy labels under administrator or trusted infrastructure control. A class name or label does not establish device ownership; administrators must configure the device selectors on the class and the DRA driver for the intended access and isolation.

Keep namespace labels that select more permissive profiles under platform control. A rule scoped to device-profile: gpu does not constrain other namespaces unless another rule covers them. The reference example below denies all class references first, then grants access in selected namespaces.

Class restrictions do not prevent administrative DRA requests. Apply the DRA administrative access baseline separately to keep administrative access disabled in application namespaces.

Reference

Grant GPU classes in selected namespaces

This Tenant denies all class references by default. Namespaces labeled device-profile: gpu receive a later grant for exact names, a name pattern, or administrator-controlled class labels. A final deny excludes quarantined classes from that grant.

apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  owners:
    - kind: User
      name: alice
  rules:
    - enforce:
        action: deny
        devices:
          classes:
            - exp: ".*"
    - namespaceSelector:
        matchLabels:
          device-profile: gpu
      enforce:
        action: allow
        devices:
          classes:
            - exact:
                - solar-gpu
            - exp: "^solar-gpu-[a-z0-9-]+$"
            - selector:
                matchLabels:
                  devices.example.com/tenant: solar
                  devices.example.com/pool: gpu
    - namespaceSelector:
        matchLabels:
          device-profile: gpu
      enforce:
        action: deny
        devices:
          classes:
            - selector:
                matchLabels:
                  devices.example.com/quarantined: "true"

The namespace selector matches namespace labels. The nested class selectors match DeviceClass labels. This example assumes administrators have created the referenced DeviceClasses with appropriate device selectors. An empty class label set does not satisfy either class selector.

Namespace or requestResult with this example
Namespace without device-profile: gpuEvery class reference is denied by the first rule.
Selected namespace, existing solar-gpu, not quarantinedAllowed by the exact-name grant.
Selected namespace, existing solar-gpu-h100, not quarantinedAllowed by the name-expression grant.
Selected namespace, another existing class with both tenant: solar and pool: gpu labels under devices.example.com/, not quarantinedAllowed by the class selector.
Selected namespace, class with devices.example.com/quarantined: "true"Denied by the final rule, even if its name matches a grant.
Selected namespace, unapproved class in any fallbackThe entire claim or template is denied.
Another Tenant’s namespaceThis Tenant’s rules do not apply there.

For example, this ResourceClaim is rejected in a selected namespace when other-gpu is an existing class that matches none of the grants, even though solar-gpu is allowed:

apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
  name: gpu
  namespace: solar-production
spec:
  devices:
    requests:
      - name: accelerator
        firstAvailable:
          - name: preferred
            deviceClassName: solar-gpu
          - name: fallback
            deviceClassName: other-gpu

Both alternatives must be allowed. For a ResourceClaimTemplate, place the same device requests under spec.spec.devices.requests. Claims subsequently generated from an admitted template are checked again against the current namespace profile.