Files
zeekay 5e04d411e2 refactor(attest): consume the github.com/luxfi/cc leaf; KindNRAS→KindNVTrust
The canonical attestation verifier (cc/attest + pkg/attestation/nvidia) was
extracted into the orthogonal leaf module github.com/luxfi/cc so mpc, the TEE
custody extension, and the confidential-AI system can share ONE verifier
coupled to none of their domains.

- pkg/attestation/composite.go, pkg/kms/release.go: import the leaf
  github.com/luxfi/cc/attest directly; map the NVIDIA issuer to the real
  KindNVTrust (was the KindNRAS stub).
- pkg/attestation/nvidia + cc/attest/{sev,tdx,verifier,...}.go: moved to the
  leaf (clean stdlib/go-sev-guest leaves, zero mpc-internal imports).
- cc/attest now a thin TRANSITION ADAPTER: a zero-logic re-export of the leaf
  (type aliases ⇒ identical types, so the kms.CompositeAttestation release
  gate is satisfied from either import path) plus the deprecated KindNRAS
  symbol that pinned github.com/luxfi/threshold v1.9.9 still references. To be
  removed once threshold republishes against the leaf (its main already has)
  and mpc's threshold/protocols/tfhe dep is resolved.

go.mod: require github.com/luxfi/cc (local replace ../cc until tagged);
threshold stays v1.9.9 (cannot bump: main drops protocols/tfhe that pkg/mpc
needs). go vet ./... clean; attestation/kms/scheduler tests green.
2026-06-27 12:33:40 -07:00

223 lines
7.1 KiB
Go

// Package scheduler enforces workload-policy gates BEFORE a worker is
// allowed to participate in a sign / inference session.
//
// The scheduler is the only place that decides "this worker may produce
// a partial signature share for this workload". Every entry point into
// the MPC sign path consults this gate. Failure FAILS CLOSED — no
// fallback to "trust the coordinator".
//
// The types here are the scheduler's own view of v0.60 registry types.
// When pkg/registry lands the WorkloadPolicy / Worker structs they
// will be adapted via the WorkloadPolicySource interface — no code in
// this package changes.
package scheduler
import (
"errors"
"fmt"
)
// TrustMode classifies a worker's confidential-compute posture, ordered
// least-to-most trusted. The gate compares with >=, so callers can
// require a minimum tier.
type TrustMode uint8
const (
// TrustNone — no confidential compute. Bare-metal or VM with no
// memory encryption. Acceptable only for public workloads.
TrustNone TrustMode = iota
// TrustCVM — CPU TEE only (SEV-SNP, TDX). Memory encrypted, CPU
// attested. GPU runs in plaintext.
TrustCVM
// TrustGPU — CPU TEE + GPU confidential compute (Hopper CC, Blackwell
// CC). End-to-end PCIe encryption between CPU TEE and GPU.
TrustGPU
// TrustGPUMultiNode — TrustGPU + NVSwitch attested for multi-GPU
// workloads. Required for tensor-parallel inference of large models.
TrustGPUMultiNode
)
// String returns the canonical name for the trust tier.
func (t TrustMode) String() string {
switch t {
case TrustNone:
return "none"
case TrustCVM:
return "cvm"
case TrustGPU:
return "gpu"
case TrustGPUMultiNode:
return "gpu_multinode"
}
return "invalid"
}
// IOLevel classifies the network/storage isolation of a worker. Used
// to enforce private-lane requirements (no egress to public internet,
// keys encrypted at rest with org-controlled keys, etc.).
type IOLevel uint8
const (
// IOPublic — public internet I/O permitted. Lowest tier.
IOPublic IOLevel = iota
// IOPrivateNet — egress restricted to allowlisted peers; ingress
// behind authenticated gateway.
IOPrivateNet
// IOPrivateLane — IOPrivateNet + storage encryption at rest with
// customer-controlled keys; no shared mounts; per-tenant volumes.
IOPrivateLane
)
// String returns the canonical name for the I/O tier.
func (l IOLevel) String() string {
switch l {
case IOPublic:
return "public"
case IOPrivateNet:
return "private_net"
case IOPrivateLane:
return "private_lane"
}
return "invalid"
}
// Worker is the scheduler's view of a candidate node for a session.
// All fields are populated by the registry from attested measurements
// (see github.com/luxfi/cc/attest/nvidia for the GPU side).
type Worker struct {
ID string
TrustMode TrustMode
IOLevel IOLevel
KernelManifestRoot [32]byte // root of approved CUDA/CPU kernel manifest
GPUAttested bool // composite NVIDIA attestation verified
CPUAttested bool // SEV-SNP / TDX quote verified
Online bool // worker is reachable + healthy
}
// WorkloadPolicy is the scheduler's view of the policy a workload
// requires of any worker that participates in it.
//
// Each field is a HARD floor — workers below the floor are ineligible.
type WorkloadPolicy struct {
WorkloadID string
MinTrust TrustMode
MinIO IOLevel
RequireModelConfidentiality bool
ApprovedKernelRoots [][32]byte // any-of: worker's KernelManifestRoot must match one
RequireGPUAttested bool
RequireCPUAttested bool
}
// Eligible reports whether w may participate in a session under p.
// Returns the first failed gate or nil on success.
//
// The decision is fail-closed: any missing or invalid field on either
// side is a rejection. There is no "best effort" mode.
func (p *WorkloadPolicy) Eligible(w Worker) error {
if p == nil {
return errors.New("scheduler: nil workload policy")
}
if w.ID == "" {
return errors.New("scheduler: worker missing ID")
}
if !w.Online {
return fmt.Errorf("scheduler: worker %s offline", w.ID)
}
if w.TrustMode < p.MinTrust {
return fmt.Errorf("scheduler: worker %s trust=%s below required %s",
w.ID, w.TrustMode, p.MinTrust)
}
if w.IOLevel < p.MinIO {
return fmt.Errorf("scheduler: worker %s io=%s below required %s",
w.ID, w.IOLevel, p.MinIO)
}
if p.RequireGPUAttested && !w.GPUAttested {
return fmt.Errorf("scheduler: worker %s missing GPU attestation", w.ID)
}
if p.RequireCPUAttested && !w.CPUAttested {
return fmt.Errorf("scheduler: worker %s missing CPU attestation", w.ID)
}
if p.RequireModelConfidentiality {
if !w.GPUAttested {
return fmt.Errorf("scheduler: worker %s confidentiality requires GPU attestation", w.ID)
}
if len(p.ApprovedKernelRoots) == 0 {
return errors.New("scheduler: confidentiality requires approved kernel roots")
}
matched := false
var zero [32]byte
if w.KernelManifestRoot == zero {
return fmt.Errorf("scheduler: worker %s missing KernelManifestRoot", w.ID)
}
for _, r := range p.ApprovedKernelRoots {
if r == w.KernelManifestRoot {
matched = true
break
}
}
if !matched {
return fmt.Errorf("scheduler: worker %s KernelManifestRoot not in approved set", w.ID)
}
}
return nil
}
// PolicySource resolves the WorkloadPolicy for a workload ID. The
// concrete implementation lives in pkg/registry (sibling v0.60); this
// package only depends on the interface.
type PolicySource interface {
Lookup(workloadID string) (*WorkloadPolicy, error)
}
// Scheduler binds a PolicySource so callers can run eligibility checks
// without threading the source through every call site.
type Scheduler struct {
src PolicySource
}
// New returns a Scheduler bound to src. src must be non-nil.
func New(src PolicySource) *Scheduler {
if src == nil {
panic("scheduler: nil PolicySource")
}
return &Scheduler{src: src}
}
// Eligible looks up the policy for workloadID and applies it to w.
// Returns nil iff w is permitted to participate.
func (s *Scheduler) Eligible(w Worker, workloadID string) error {
p, err := s.src.Lookup(workloadID)
if err != nil {
return fmt.Errorf("scheduler: lookup %s: %w", workloadID, err)
}
if p == nil {
return fmt.Errorf("scheduler: no policy for workload %s", workloadID)
}
return p.Eligible(w)
}
// StaticPolicySource is an in-memory PolicySource. Useful for tests and
// for the legacy single-policy deployment mode where the policy is
// loaded from config at startup.
type StaticPolicySource struct {
policies map[string]*WorkloadPolicy
}
// NewStaticPolicySource constructs a StaticPolicySource from a map.
func NewStaticPolicySource(m map[string]*WorkloadPolicy) *StaticPolicySource {
cp := make(map[string]*WorkloadPolicy, len(m))
for k, v := range m {
cp[k] = v
}
return &StaticPolicySource{policies: cp}
}
// Lookup returns the policy for workloadID or an error if absent.
func (s *StaticPolicySource) Lookup(workloadID string) (*WorkloadPolicy, error) {
p, ok := s.policies[workloadID]
if !ok {
return nil, fmt.Errorf("workload %s not registered", workloadID)
}
return p, nil
}