Component-scoped input
The input a component-scoped policy receives, with TypeScript types and a sample.
This page lists the JSON input a component-scoped policy receives, whether it is built in the Visual Builder or written in Rego or JavaScript. Use it to look up a field name or to build test input. For how to write a policy, see Write and test policies; for how the index behind this input is built, see Data model fundamentals.
Top-level fields
A component-scoped policy is called once per component, with the component and vulnerabilities fields populated:
{
component: { ... },
vulnerabilities: [ ... ],
namespace: { tenantId, space }
}TypeScript types
Below is the input as TypeScript types. Not every field is set on every input, so check for missing values in a policy.
// this is the top-level object that is passed to the policy
type PolicyInputType = {
namespace?: Namespace;
component?: Component;
vulnerabilities?: Vulnerability[];
};
type Namespace = {
tenantId: OrganizationId;
space: string;
};
type Component = {
id: ComponentRef;
type: ComponentType;
packageUrl?: string; // https://github.com/package-url/purl-spec
name: string;
group?: string;
version?: string;
lifecycle?: ComponentLifecycle;
supplier?: Supplier;
manufacturer?: Supplier;
externalReferences?: ExternalReference[];
hashes?: Record<string, string>;
provenance?: ComponentProvenance;
licenses?: LicenseChoice[];
modelCard?: ModelCard;
scope?: Scope;
isExternal?: boolean;
versionRange?: string;
annotation?: ComponentAnnotation;
properties?: Record<string, string>;
createdAt?: string;
updatedAt?: string;
};
type ComponentLifecycle = {
endOfDevelopment?: string; // date string "YYYY-MM-DD"
endOfSupport?: string;
endOfLife?: string;
endOfDistribution?: string;
};
type ComponentAnnotation = {
id: ComponentRef;
displayName?: string;
license?: string;
lifecycle?: ComponentLifecycle;
supplierId?: SupplierId;
manufacturerId?: SupplierId;
businessCriticality?: BusinessCriticality;
internal?: boolean;
properties?: Record<string, string>;
notes?: string;
tags?: string[];
createdAt?: string;
updatedAt?: string;
};
type Vulnerability = {
id: VulnerabilityId;
component: ComponentRef;
advisoryId: string;
severity: number;
vendorId: string;
epss: number;
vex?: VulnerabilityAnalysis;
};
type ImpactAnalysisResponse =
| "can_not_fix"
| "will_not_fix"
| "update"
| "rollback"
| "workaround_available";
type ImpactAnalysisState =
| "resolved"
| "resolved_with_pedigree"
| "exploitable"
| "in_triage"
| "false_positive"
| "not_affected";
type ImpactAnalysisJustification =
| "code_not_present"
| "code_not_reachable"
| "requires_configuration"
| "requires_dependency"
| "requires_environment"
| "protected_by_compiler"
| "protected_at_runtime"
| "protected_at_perimeter"
| "protected_by_mitigating_control";
type VulnerabilityAnalysis = {
id: VulnerabilityAnalysisId;
vulnerability: string; // vendor id CVE-2019-1234 etc
affects?: ComponentRef[];
state?: ImpactAnalysisState;
justification?: ImpactAnalysisJustification;
response?: ImpactAnalysisResponse[];
details?: string;
author?: UserId;
issueOwner?: UserId;
attestations?: string[]; // sha256
externalReferences?: string[]; // links etc
published: string;
createdAt: string;
updatedAt: string;
};
type SupplierType = "ORGANIZATION" | "PERSON";
type Supplier = {
id?: SupplierId;
name: string;
type: SupplierType;
address?: OrganizationalPostalAddress;
url?: string[];
contact?: OrganizationalContact[];
createdAt?: string;
updatedAt?: string;
annotation?: SupplierAnnotation;
};
type SupplierAnnotation = {
id?: SupplierId;
displayName?: string;
url?: string;
contact?: OrganizationalContact;
address?: OrganizationalPostalAddress;
lei?: string;
vat?: string;
eori?: string;
euid?: string;
brn?: string;
internalId?: string;
cpeVendor?: string;
duns?: string;
uei?: string;
cage?: string;
gln?: string;
iso6523?: string;
notes: string;
properties?: Record<string, string>;
tags?: string[];
createdAt?: string;
updatedAt?: string;
};
type OrganizationalContact = {
name?: string;
email?: string;
phone?: string;
};
type OrganizationalPostalAddress = {
country?: string;
region?: string;
locality?: string;
postOfficeBoxNumber?: string;
postalCode?: string;
streetAddress?: string;
};
type ExternalReference = {
type: ExternalReferenceType;
url?: string;
hashes?: Record<string, string>;
};
type License = {
id?: string;
name?: string;
url?: string;
};
type LicenseChoice = {
license?: License;
expression?: string;
};
type BusinessCriticality = "high" | "medium" | "low";
type ModelCard = Record<string, any>;
type Scope = string;
type ComponentProvenance = {
attestation?: string;
provenanceUrl?: string;
slsaVersion?: string;
slsaVersionUrl?: string;
builderId?: string;
builderName?: string;
builderUrl?: string;
logIndex?: number;
logEntryUrl?: string;
logIntegratedTime?: number;
repository?: string;
repositoryUrl?: string;
repositoryDigest?: string;
buildConfigUrl?: string;
buildConfigPath?: string;
invocationId?: string;
invocationUrl?: string;
};
type ComponentRef = string;
type ComponentType = string;
type ExternalReferenceType = string;
type VulnerabilityId = string;
type VulnerabilityAnalysisId = string;
type OrganizationId = string;
type UserId = string;
type SupplierId = string;Sample policy input
To test a Rego policy, paste this into the Input field of the Rego Playground. Visual Builder and JavaScript policies receive the same structure.
{
"component": {
"id": "34c0f4772324dec6d00af7127a6f7454f655bc0d",
"packageUrl": "pkg:npm/zod@3.21.4",
"type": "library",
"version": "3.21.4",
"name": "zod",
"licenses": [{ "license": { "name": "MIT" } }],
"createdAt": "2023-10-30T18:28:35.757164+01:00",
"updatedAt": "2023-10-30T18:28:35.761883+01:00"
},
"vulnerabilities": [
{
"id": "8820c737e3913979bead47ce9e309ea153e1f7d1",
"severity": 7.5,
"vendorId": "CVE-2023-4316",
"epss": 0.00046,
"vex": {
"state": "not_affected",
"justification": "requires_configuration"
}
},
{
"id": "a1b2c3d4e5f69780b1c2d3e4f5a67890b1c2d3e4",
"severity": 8.8,
"vendorId": "CVE-2023-9999",
"epss": 0.6
}
],
"namespace": {
"tenantId": "org-4dec6d00af7127a6",
"space": "default"
}
}To test another case, keep the top-level component, vulnerabilities, and namespace keys and change the objects under them.
Use vulnerabilities[].vex.state to skip vulnerabilities that a VEX analysis marks not_affected, false_positive, resolved, or resolved_with_pedigree, instead of keeping an allowlist in the policy.
Related
- How-to: Write and test policies, Enforce policies in CI/CD
- Concept: Policies
- Reference: Suppliers for supplier-specific policy examples.