Using AICR as a Go library
AICR ships as both a CLI and a Go library. External projects that need to resolve validated recipes, generate bundles, or collect observed state can import AICR directly. This page is for those consumers.
Which package to import
Import the github.com/NVIDIA/aicr/pkg/client/v1 package. This is the
stable facade.
The facade provides a single Client type with constructors for the
supported recipe sources. Internally it delegates to the functional
packages under pkg/*.
You may also import pkg/* subpackages directly, but their APIs are
not covered by the same stability guarantees — see the public API
surface for the details.
Installing
For reproducibility in downstream projects, pin a specific tag:
Quick start
Snapshotting and validation
Beyond recipe resolution, the facade exposes the rest of the Snapshot → Validate workflow. Both methods are stateless w.r.t. the Client’s recipe source; they are surfaced through the Client only to keep the facade uniform and leave room for future per-Client telemetry hooks.
The recipe argument to ValidateState MUST be the *RecipeResult
returned by the same Client’s ResolveRecipe (or LoadRecipe) call —
the unexported internal recipe state is required for constraint
evaluation.
To restrict the run to specific phases, pass WithValidationPhases in
the order you want them executed:
Valid phase values are PhaseDeployment, PhaseConformance, and
PhasePerformance (canonical execution order). An unrecognized phase is rejected with
ErrCodeInvalidRequest before any cluster work, so a typo cannot
silently degrade to an empty run.
Loading an existing recipe
When a recipe has already been resolved and persisted (for example a
recipe file checked into a GitOps repo, or a cm:// ConfigMap URI), load
it back through the same Client with LoadRecipe instead of re-resolving
from criteria:
LoadRecipe hydrates overlay inputs (kind: RecipeMetadata) against the
Client’s own data provider and returns a Client-owned *RecipeResult
ready for ValidateState / BundleComponents — it passes the same
ownership check as a ResolveRecipe result. An already-hydrated
RecipeResult file is returned with its provider bound to the Client.
The kubeconfig argument (third parameter) is only needed when the recipe
path (first argument) is a cm:// ConfigMap URI.
For unit tests that exercise the facade surface without a live
cluster, pass aicr.WithValidationNoCluster(true): every check
reports as “skipped - no-cluster mode” and no Kubernetes resources
are created. Other facade options
(WithValidationNamespace, WithValidationRunID,
WithValidationCleanup, WithValidationImagePullSecrets,
WithValidationTolerations, WithValidationNodeSelector) cover the
production-controller knobs.
Recipe sources
AICR exposes one production recipe source today; pick it via
aicr.WithRecipeSource:
EmbeddedSource resolves against the recipe data compiled into the
AICR binary — no filesystem path required. Use it when you want AICR’s
bundled recipe data and no local overrides. FilesystemSource
layers an external directory over that same embedded data, so files in
the directory override their embedded equivalents.
Client options
Beyond WithRecipeSource, NewClient accepts these functional options:
WithVersion(version string)stamps the given version string into resolved recipe metadata (accessible viaresult.Resolved().Metadata.Version). Typically the consuming binary’s build version.WithAllowLists(al *AllowLists)fences which criteria values the Client’s resolve path accepts. A resolve whose criteria fall outside the allowlist is rejected before the recipe is built. Passnil(or omit the option) to allow all values.ParseAllowListsFromEnv()builds anAllowListsfrom theAICR_ALLOWED_ACCELERATORS,AICR_ALLOWED_SERVICES,AICR_ALLOWED_INTENTS, andAICR_ALLOWED_OSenvironment variables. It returnsnilwhen none are set —WithAllowListstreats anilAllowListsas allow-all, so the result is always safe to pass straight toWithAllowLists.
AllowLists is a facade-owned struct whose Accelerators, Services,
Intents, and OSTypes fields are plain []string slices, so callers
can construct one directly without depending on pkg/recipe’s enum
identifiers. When you already hold a pkg/recipe.AllowLists, use
aicr.WrapAllowLists to project it onto the facade shape.
Resolving from criteria
ResolveRecipe takes the stable RecipeRequest shape and returns the
facade RecipeResult — a deliberately small struct exposing the
Name, Version, and Components of the resolved recipe. When you
already hold an *aicr.Criteria value — for example, a REST handler
that parsed criteria from an incoming HTTP request and wrapped them with
aicr.WrapCriteria — use ResolveRecipeFromCriteria. It returns the
same facade *RecipeResult; call result.Resolved() when you need the
complete underlying *pkg/recipe.RecipeResult (constraints, deployment
order, validation config, metadata):
The returned *RecipeResult carries:
Name,Version,TranslatedAt— stable identityComponents—[]ComponentRef(Name, Kind, Version, Source, Chart, Namespace)Resolved()— the upstream*pkg/recipe.RecipeResultfor callers that need constraints, deployment order, validation config, or metadata (e.g., evidence emission). Do not mutate; do not retain past the facadeRecipeResult’s lifetime — marshal first if persistence is needed.
Criteria is a facade-owned struct whose enum-typed fields project to
plain strings, decoupling the public surface from pkg/recipe’s enum
identifiers. Construct one directly or wrap an upstream
*pkg/recipe.Criteria via aicr.WrapCriteria. Allowlist enforcement
(WithAllowLists) applies here just as it does on ResolveRecipe; a
nil Client, nil context, or nil criteria each return
ErrCodeInvalidRequest, and the same facade-level timeout bounds the
resolve.
To extract a single value from a resolved recipe, use
SelectFromRecipe with a dot-path selector. It hydrates the recipe’s
component values and returns the value at the path; an empty selector
returns the entire hydrated structure, and a nil *RecipeResult
returns ErrCodeInvalidRequest. This mirrors the aicr query CLI
command:
Errors
All errors returned by the facade are *pkg/errors.StructuredError
values carrying an ErrorCode. Use errors.As to inspect:
Context handling
ResolveRecipe (and every other context-aware facade method) honours
context cancellation. Each facade entry point unconditionally wraps the
caller’s context with context.WithTimeout against its per-operation
cap. The effective deadline is the smaller of the caller’s deadline
and the facade cap, per context.WithTimeout semantics — a caller
passing a tighter deadline keeps it; a caller passing
context.Background() gets the facade cap.
Per-operation caps:
ResolveRecipe/BundleComponents:defaults.RecipeOperationTimeoutCollectSnapshot: caller-controlled viaAgentConfig.Timeout, falling back todefaults.SnapshotOperationTimeoutwhen unsetValidateState:defaults.ValidationOperationTimeoutMakeBundle: opt-in viaBundleOptions.Timeout. When unset (0) the caller’s context governs unchanged — large bundles,--vendor-charts, and attestation/signing can exceed any fixed cap. The REST/v1/bundlehandler sets it todefaults.BundleHandlerTimeout; the CLIbundlecommand leaves it0.
Passing a nil context.Context returns ErrCodeInvalidRequest. Use
context.Background() (or a deadline-bounded child) for unbounded callers.
Compatibility
The facade’s exported API follows Semantic Versioning:
- Major bumps may rename, remove, or change the shape of exported types and function signatures.
- Minor bumps may add new exported types, fields, or methods.
- Patch bumps are bug-fix-only.
Today AICR is pre-1.0. Pin a patch version in your go.mod and
audit diffs on upgrade.
See also
- Public API surface — stability matrix per package
- Automation guide — CI integration patterns
- Recipe development — authoring recipes