@fourier-labs/harbour-contracts 0.66.0 → 0.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/contract-release.json +14 -14
- package/dist/gen-ts/ai-policy-snapshot.d.ts +6 -0
- package/dist/gen-ts/contract-release.d.ts +6 -6
- package/dist/gen-ts/contract-release.js +6 -6
- package/dist/gen-ts/index.d.ts +1 -1
- package/dist/gen-ts/index.js +1 -1
- package/dist/gen-ts/security-scan-input-v2.d.ts +74 -0
- package/dist/gen-ts/security-verdict.d.ts +32 -11
- package/gen-ts/ai-policy-snapshot.ts +6 -0
- package/gen-ts/contract-release.ts +6 -6
- package/gen-ts/index.ts +1 -1
- package/gen-ts/security-scan-input-v2.ts +77 -0
- package/gen-ts/security-verdict.ts +32 -11
- package/package.json +1 -1
- package/schema/ai-policy-snapshot.schema.json +8 -1
- package/schema/security-scan-input-v2.schema.json +79 -0
- package/schema/security-verdict.schema.json +24 -13
- package/dist/gen-ts/security-scan-input.d.ts +0 -88
- package/gen-ts/security-scan-input.ts +0 -91
- package/schema/security-scan-input.schema.json +0 -110
- /package/dist/gen-ts/{security-scan-input.js → security-scan-input-v2.js} +0 -0
package/README.md
CHANGED
|
@@ -55,8 +55,8 @@ exist here first.
|
|
|
55
55
|
| `transform-parked-result.schema.json` | Sequential-preview result after a durable checkpoint when builder input is required; not a successful report | — |
|
|
56
56
|
| `builder-input-proposal.schema.json` | Value-free proposal emitted when sequential preview cannot continue without builder-owned input | — |
|
|
57
57
|
| `deployment-continuation.schema.json` | Immutable reference admitting one child deployment from a parked input request; never credential values | — |
|
|
58
|
-
| `security-scan-input.schema.json` | Input to the Security Assurance machine
|
|
59
|
-
| `security-verdict.schema.json` | Security Assurance decision; `BLOCKED` surfaces as the non-retryable `gate.security-scan` category |
|
|
58
|
+
| `security-scan-input-v2.schema.json` | Input to the Security Assurance machine (`harbour.security-scan-input/2.0`, replaces v1): one package validated at source intake, scanned in the tenant's execution account | ADR 0014 |
|
|
59
|
+
| `security-verdict.schema.json` | Security Assurance decision; `BLOCKED` surfaces as the non-retryable `gate.security-scan` category | ADR 0014 |
|
|
60
60
|
| `data-source.schema.json` | Admin-registered external data source; `credentialRef` is a secretref URI and the credential never crosses this boundary | Data-Access MVP |
|
|
61
61
|
| `data-dependency.schema.json` | One external data dependency of an app, declared or detected, classified against the tenant's data-source inventory | Data-Access MVP |
|
|
62
62
|
| `secret-reference.schema.json` | Named secret slot an app depends on; only the reference and its lifecycle cross, never the value | Secret-Manager MVP |
|
package/contract-release.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "harbour.contract-release/1.0",
|
|
3
|
-
"repositoryVersion": "0.
|
|
4
|
-
"publishVersion": "0.
|
|
5
|
-
"publishTag": "v0.
|
|
6
|
-
"schemasDigest": "sha256:
|
|
3
|
+
"repositoryVersion": "0.68.0.0",
|
|
4
|
+
"publishVersion": "0.68.0",
|
|
5
|
+
"publishTag": "v0.68.0",
|
|
6
|
+
"schemasDigest": "sha256:3860585b4a4a55334e788faca34018dfaa21bf7ee5fa42bb50b0a454a77047b3",
|
|
7
7
|
"aiFixturesDigest": "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6",
|
|
8
|
-
"generatedGoDigest": "sha256:
|
|
9
|
-
"generatedTypeScriptDigest": "sha256:
|
|
8
|
+
"generatedGoDigest": "sha256:0c97fd145737bf8fba6de780187033f04e52fe524284cd95c084fcda38e31a28",
|
|
9
|
+
"generatedTypeScriptDigest": "sha256:bd9927f250e96a91958f078ea29d1420ca3d6545ce93b2b2901033ac09e52827",
|
|
10
10
|
"generatedExclusions": {
|
|
11
11
|
"gen-go/contract_release.go": "contains the generated aggregate digests (self-reference)",
|
|
12
12
|
"gen-ts/contract-release.ts": "contains the generated aggregate digests (self-reference)"
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"schema/ai-gateway-key-lookup.schema.json": "sha256:7d362ded73c0da6b433f3c73afeabea4c38c5d6fc92c391c7ded727324deddf2",
|
|
22
22
|
"schema/ai-governance-decision.schema.json": "sha256:d650762a428350748deafd6b251cbd4a03ba564650e74204f1a77bbe923e145f",
|
|
23
23
|
"schema/ai-metering-policy.schema.json": "sha256:044115938d254d914feac162219d20ee48f741cd7ad32df4613b45f9c862fe8c",
|
|
24
|
-
"schema/ai-policy-snapshot.schema.json": "sha256:
|
|
24
|
+
"schema/ai-policy-snapshot.schema.json": "sha256:40c0c4af4245a479c9b6d11d79f107ae3a6002a83de632ee9a92deb9ae9a630b",
|
|
25
25
|
"schema/ai-pricing-revision.schema.json": "sha256:5ddb40c23712c0cec37b733678e4bb34811f5db44a233773c21a7dfaec188375",
|
|
26
26
|
"schema/ai-runtime-binding.schema.json": "sha256:e99f983e78478b50114e0b2c940bb5bb30a4645cfd7fbddb7e0cf161d6d28502",
|
|
27
27
|
"schema/ai-runtime-contract.schema.json": "sha256:bfa2f8968b1c0678b328c178c7b9c6563f7a363ae04bf74a1078a1cd9679fa14",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"schema/saas-connection.schema.json": "sha256:82ed8018201800a95aa792bde1d22568e86b55b3be926aa094a260c8c78a58d7",
|
|
67
67
|
"schema/sanitized-binding-evidence.schema.json": "sha256:1191ab88e2764df927e5f17837674cebebe068d480da2b2fdb390e589f96b51f",
|
|
68
68
|
"schema/secret-reference.schema.json": "sha256:db4e3c2c6a2dbd72d7ea0f9c91cb3b2343a7e67b601996c6818b2ef08e440895",
|
|
69
|
-
"schema/security-scan-input.schema.json": "sha256:
|
|
70
|
-
"schema/security-verdict.schema.json": "sha256:
|
|
69
|
+
"schema/security-scan-input-v2.schema.json": "sha256:adf90e7e158e2a29145fa9696219dad82d294cac14614bcd10910a251ebe6940",
|
|
70
|
+
"schema/security-verdict.schema.json": "sha256:6650c327b58431c6a567bbbf1e59bb9d4a8dc2f0ff2efc92ca4c2fd5b2cf28b6",
|
|
71
71
|
"schema/transform-parked-result.schema.json": "sha256:11729980d4c89d4a9e18f5f213232cd3359739c85626b36c20c2a37ba794c9af",
|
|
72
72
|
"schema/transform-report.schema.json": "sha256:b9b4b09f88714b49d855f01ab9b611f34fb856447c0d063be409bb12a6c2700a",
|
|
73
73
|
"schema/version-state.schema.json": "sha256:3b190007e2f8e3821c41ef11c6f5b226da7d5a18d34d4077f4618004846fd444",
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
"gen-go/integration_execute_input_rules.go": "sha256:52a405aa7a97f7b4e2ed3c314a7bd28b7698cc7883ee72ad4c027637be602ab9",
|
|
113
113
|
"gen-go/integration_execute_input_rules_test.go": "sha256:c437a8406a2f062a0173b9419e4cb176fc6eb54e569506225d5162323f55b40b",
|
|
114
114
|
"gen-go/schema_documents.go": "sha256:c19c0d540f602ee997a84b90e20702d9bc63ed7d27aec267e76c04655fc182e0",
|
|
115
|
-
"gen-go/types.go": "sha256:
|
|
115
|
+
"gen-go/types.go": "sha256:e700fb22b4e2eb59f8531da4bdac154ac22991f9fd39e72b2f4483e1fa2e0264",
|
|
116
116
|
"gen-go/version_state.go": "sha256:4ef8abb126414c0025cf2c59bc9c79a74ef4a2ff89e8f316cbf05acc872371c1"
|
|
117
117
|
},
|
|
118
118
|
"generatedTypeScript": {
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"gen-ts/ai-gateway-key-token.ts": "sha256:ff6551ad3332cc665878d7ec93f42ce185c375e637531b2fbc82c697b877e784",
|
|
128
128
|
"gen-ts/ai-governance-decision.ts": "sha256:4a04e116f2ec281104e616a8ba414f23a9d34d398f850888d27510173e39c5c3",
|
|
129
129
|
"gen-ts/ai-metering-policy.ts": "sha256:dd261d57646a509cd46efaefac4aad58d018c7f7da98326dd8859e4ce951c56a",
|
|
130
|
-
"gen-ts/ai-policy-snapshot.ts": "sha256:
|
|
130
|
+
"gen-ts/ai-policy-snapshot.ts": "sha256:d0515a20dae4c6ae25220d1bb5025339918c8c9bc66817ea3fb2090a9b6bed02",
|
|
131
131
|
"gen-ts/ai-pricing-revision.ts": "sha256:48afdea7fb09b9a392147a0a62bcee013157a9d536c07e0782ef28781a3000de",
|
|
132
132
|
"gen-ts/ai-runtime-binding.ts": "sha256:3930989c01e2b90041b5a8f9eaf9d8612854c9088090ca82e5687b85f26e106f",
|
|
133
133
|
"gen-ts/ai-runtime-contract.ts": "sha256:6ed3bde6ab7a3f7e2e298c2904eb52d35e06699c5e284f98fb39abfc76858beb",
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"gen-ts/error-category-registry.ts": "sha256:7466a502c0723a77db825cdeaa9556a244201b55d9b7acbf2c098e9e84351df1",
|
|
161
161
|
"gen-ts/error-category.ts": "sha256:9bda89180c3b740c9aa8be466216592e8ca9d0d368c274333edf6ea5c45afd8e",
|
|
162
162
|
"gen-ts/error-envelope.ts": "sha256:4457309be794f9d4fc0cf62530cc2d442c007bac9ae84aff66df099cc9e40310",
|
|
163
|
-
"gen-ts/index.ts": "sha256:
|
|
163
|
+
"gen-ts/index.ts": "sha256:8459b1cf136a0c822795154e2df2a28c848cddfadced329604be893ae6eef069",
|
|
164
164
|
"gen-ts/integration-connect-result.ts": "sha256:4b10f169b6e1af364e9b418de21caa9fadbfb77b43cbff77d741cfae0b52180c",
|
|
165
165
|
"gen-ts/integration-error-details.ts": "sha256:ad7ecec9dd4533a6e86b3508886a7d69937052f52105497285797f77106bcc6f",
|
|
166
166
|
"gen-ts/integration-execute-input-rules.ts": "sha256:0da117ac9f3109462e5862d658edf0f50e4b71fdcbb675d3a9dcb08489bcadd0",
|
|
@@ -177,8 +177,8 @@
|
|
|
177
177
|
"gen-ts/sanitized-binding-digest-helper.ts": "sha256:c47d7fdc20500e2e72c23fe39ecdd610fc397c47fcba51335ebec3c380fe6872",
|
|
178
178
|
"gen-ts/sanitized-binding-evidence.ts": "sha256:f3fb7b1d7d2e0929eb0ea981eaf32db3104010647185f6ae59f67167d42538a9",
|
|
179
179
|
"gen-ts/secret-reference.ts": "sha256:731fbcde7315cb4128d5b01bdbe6e6f248f13c7ad8dea04a3a4e927ac4890198",
|
|
180
|
-
"gen-ts/security-scan-input.ts": "sha256:
|
|
181
|
-
"gen-ts/security-verdict.ts": "sha256:
|
|
180
|
+
"gen-ts/security-scan-input-v2.ts": "sha256:ec703b8fe1734a623ce138adc54dc7acbe3b0880e469c70e8bf8f94d7ddb85c2",
|
|
181
|
+
"gen-ts/security-verdict.ts": "sha256:c7c4c82183e7996941cee93a9cdb4dcaa8a4dab2d607ce29aab8683ee5ced8eb",
|
|
182
182
|
"gen-ts/transform-parked-result.ts": "sha256:6279e27cee8d75c29f3ede45580fef1daa0ca300867a78e43ead8a7689ec613f",
|
|
183
183
|
"gen-ts/transform-report.ts": "sha256:d83f1c34c4a082bd80bf9588b08e2fba3b7e25cd1855375ca3073ab9fafddfec",
|
|
184
184
|
"gen-ts/version-state-machine.ts": "sha256:c67af3e86ac306743345b850dfd3ae5201c19d10c40e2c149cf8c38258320d5f",
|
|
@@ -106,6 +106,12 @@ export interface AiPolicyModel {
|
|
|
106
106
|
capabilities: ('generation' | 'embeddings' | 'transcription' | 'translation' | 'speech' | 'image' | 'video' | 'realtime')[];
|
|
107
107
|
approved: boolean;
|
|
108
108
|
pricing: AiPolicyPricing;
|
|
109
|
+
/**
|
|
110
|
+
* What the development kit can do with this model through the Gateway, declared by the tenant for a model it adds beyond the Isomorph catalogue (ADR 0015). Absent keeps the earlier vendor-derived answers; an empty list declares none. Governance ignores it on a catalogue model and caps kitSdkCompatible, streaming and imageEdit by the vendor. The Gateway does not read it.
|
|
111
|
+
*
|
|
112
|
+
* @maxItems 5
|
|
113
|
+
*/
|
|
114
|
+
features?: ('kitSdkCompatible' | 'toolCalling' | 'streaming' | 'imageInput' | 'imageEdit')[];
|
|
109
115
|
}
|
|
110
116
|
export interface AiPolicyPricing {
|
|
111
117
|
revision: AiPolicyIdentifier;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export declare const ContractRepositoryVersion: "0.
|
|
2
|
-
export declare const ContractPublishVersion: "0.
|
|
3
|
-
export declare const ContractPublishTag: "v0.
|
|
4
|
-
export declare const ContractSchemasDigest: "sha256:
|
|
1
|
+
export declare const ContractRepositoryVersion: "0.68.0.0";
|
|
2
|
+
export declare const ContractPublishVersion: "0.68.0";
|
|
3
|
+
export declare const ContractPublishTag: "v0.68.0";
|
|
4
|
+
export declare const ContractSchemasDigest: "sha256:3860585b4a4a55334e788faca34018dfaa21bf7ee5fa42bb50b0a454a77047b3";
|
|
5
5
|
export declare const ContractAiFixturesDigest: "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
|
|
6
|
-
export declare const ContractGeneratedGoDigest: "sha256:
|
|
7
|
-
export declare const ContractGeneratedTypeScriptDigest: "sha256:
|
|
6
|
+
export declare const ContractGeneratedGoDigest: "sha256:0c97fd145737bf8fba6de780187033f04e52fe524284cd95c084fcda38e31a28";
|
|
7
|
+
export declare const ContractGeneratedTypeScriptDigest: "sha256:bd9927f250e96a91958f078ea29d1420ca3d6545ce93b2b2901033ac09e52827";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
|
-
export const ContractRepositoryVersion = "0.
|
|
4
|
-
export const ContractPublishVersion = "0.
|
|
5
|
-
export const ContractPublishTag = "v0.
|
|
6
|
-
export const ContractSchemasDigest = "sha256:
|
|
3
|
+
export const ContractRepositoryVersion = "0.68.0.0";
|
|
4
|
+
export const ContractPublishVersion = "0.68.0";
|
|
5
|
+
export const ContractPublishTag = "v0.68.0";
|
|
6
|
+
export const ContractSchemasDigest = "sha256:3860585b4a4a55334e788faca34018dfaa21bf7ee5fa42bb50b0a454a77047b3";
|
|
7
7
|
export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6";
|
|
8
|
-
export const ContractGeneratedGoDigest = "sha256:
|
|
9
|
-
export const ContractGeneratedTypeScriptDigest = "sha256:
|
|
8
|
+
export const ContractGeneratedGoDigest = "sha256:0c97fd145737bf8fba6de780187033f04e52fe524284cd95c084fcda38e31a28";
|
|
9
|
+
export const ContractGeneratedTypeScriptDigest = "sha256:bd9927f250e96a91958f078ea29d1420ca3d6545ce93b2b2901033ac09e52827";
|
package/dist/gen-ts/index.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export * from './saas-connection.js';
|
|
|
59
59
|
export * from './sanitized-binding-digest-helper.js';
|
|
60
60
|
export * from './sanitized-binding-evidence.js';
|
|
61
61
|
export * from './secret-reference.js';
|
|
62
|
-
export * from './security-scan-input.js';
|
|
62
|
+
export * from './security-scan-input-v2.js';
|
|
63
63
|
export * from './security-verdict.js';
|
|
64
64
|
export * from './transform-parked-result.js';
|
|
65
65
|
export * from './transform-report.js';
|
package/dist/gen-ts/index.js
CHANGED
|
@@ -61,7 +61,7 @@ export * from './saas-connection.js';
|
|
|
61
61
|
export * from './sanitized-binding-digest-helper.js';
|
|
62
62
|
export * from './sanitized-binding-evidence.js';
|
|
63
63
|
export * from './secret-reference.js';
|
|
64
|
-
export * from './security-scan-input.js';
|
|
64
|
+
export * from './security-scan-input-v2.js';
|
|
65
65
|
export * from './security-verdict.js';
|
|
66
66
|
export * from './transform-parked-result.js';
|
|
67
67
|
export * from './transform-report.js';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input to the Security Assurance machine, second shape, replacing security-scan-input.schema.json. V1 scanned a deployed commit located through the deployment state; v2 scans exactly one thing: an uploaded package that governance validated at source intake, identified by the zip sha256 the stager verifies before extraction and by the tree digest governance computed from the unzipped bytes (`sourceDigestOf`, `sha256:`-prefixed), which keys the governance scan record and the check report on the laptop. Commit-mode and ARTIFACT-phase inputs are deliberately absent: the console's later on-demand scan uses this same package path against the deploy upload, and the Transform lane runs the scanner in-process; an image scan, if it returns, is an additive v3. The policy profile is named by the caller when it knows better than the data classification (the kit lane names BASELINE); `profile` and `classification` are mutually exclusive, and both absent still defaults to STANDARD with `classificationDefaulted: true`. Nothing here carries a scanner version: the scanner stamps its own into verdict provenance, and governance decides validity by comparing that against its MINIMUM_SCANNER_VERSION. `org`/`app` are the tenant and app ids for kit apps; `env` stays required because the evidence key carries it (governance passes `preview` for a package scan; promotion never re-scans). The `execution` block names the tenant's execution-account scanner, invoke role and artifacts bucket, resolved by governance the way admission resolves them for the deploy machine.
|
|
3
|
+
*/
|
|
4
|
+
export interface SecurityScanInputV2 {
|
|
5
|
+
schema: 'harbour.security-scan-input/2.0';
|
|
6
|
+
/**
|
|
7
|
+
* Isomorph organization id (the governance tenant id for kit apps), e.g. fourier.
|
|
8
|
+
*/
|
|
9
|
+
org: string;
|
|
10
|
+
/**
|
|
11
|
+
* Isomorph app id within the org (the governance appId for kit apps).
|
|
12
|
+
*/
|
|
13
|
+
app: string;
|
|
14
|
+
/**
|
|
15
|
+
* Evidence-key segment and provenance only; governance passes `preview` for a package scan.
|
|
16
|
+
*/
|
|
17
|
+
env: 'preview' | 'prod';
|
|
18
|
+
package: PackageSource;
|
|
19
|
+
execution: Execution;
|
|
20
|
+
/**
|
|
21
|
+
* Policy profile named by the caller. Takes the place of deriving one from `classification`; the verdict echoes the profile evaluated and stamps `classificationDefaulted: false`. Governance names BASELINE for kit-lane scans; the default when nothing is named is STANDARD.
|
|
22
|
+
*/
|
|
23
|
+
profile?: 'BASELINE' | 'STANDARD' | 'HIGH' | 'CRITICAL';
|
|
24
|
+
/**
|
|
25
|
+
* Data classification, mapped to a profile as in v1 (GREEN → BASELINE, YELLOW → STANDARD, ORANGE → HIGH, RED → CRITICAL). Not allowed beside `profile`. Absent with no `profile` means STANDARD and `classificationDefaulted: true`; an invalid value fails closed.
|
|
26
|
+
*/
|
|
27
|
+
classification?: 'GREEN' | 'YELLOW' | 'ORANGE' | 'RED';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The bytes `isomorph secure` (or a later console re-run against a deploy upload) put through source intake.
|
|
31
|
+
*/
|
|
32
|
+
export interface PackageSource {
|
|
33
|
+
/**
|
|
34
|
+
* Bucket holding the uploaded package zip (the governance upload bucket; the stage-package role holds a prefix-scoped read grant and the key's decrypt).
|
|
35
|
+
*/
|
|
36
|
+
bucket: string;
|
|
37
|
+
/**
|
|
38
|
+
* Object key of the package zip as the completed multipart upload left it, under the `scan/` prefix.
|
|
39
|
+
*/
|
|
40
|
+
key: string;
|
|
41
|
+
/**
|
|
42
|
+
* S3 object version to read, when the bucket is versioned, so a later re-upload under the same key cannot change what was scanned.
|
|
43
|
+
*/
|
|
44
|
+
versionId?: string;
|
|
45
|
+
/**
|
|
46
|
+
* SHA-256 of the zip bytes. The stager verifies it before extraction and it becomes the verdict's `snapshotSha256`. Governance already checked it equals the manifest's packageSha256 at intake.
|
|
47
|
+
*/
|
|
48
|
+
sha256: string;
|
|
49
|
+
/**
|
|
50
|
+
* Tree digest governance computed from the unzipped, validated package with the shared source-digest algorithm, `sha256:` prefixed as `sourceDigestOf` emits it (the same value `isomorph check` pins in check-report.json). Caller-supplied provenance echoed into the verdict; the scan record and the deploy gate are keyed by it.
|
|
51
|
+
*/
|
|
52
|
+
sourceDigest: string;
|
|
53
|
+
/**
|
|
54
|
+
* Digest of the file manifest the CLI sent, for the evidence record. Provenance only.
|
|
55
|
+
*/
|
|
56
|
+
manifestDigest?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Where the scan runs. The machine passes the function ARN and role to its one execution-account task as FunctionName and Credentials.RoleArn, exactly as the deploy machine does with its execution block.
|
|
60
|
+
*/
|
|
61
|
+
export interface Execution {
|
|
62
|
+
/**
|
|
63
|
+
* The tenant's execution-account security-scan Lambda.
|
|
64
|
+
*/
|
|
65
|
+
securityScanFunctionArn: string;
|
|
66
|
+
/**
|
|
67
|
+
* Role the machine assumes to invoke the scanner and the Harbour-side stage-package Lambda assumes to write the staged zip (harbour-preview-v2-invoke in beta).
|
|
68
|
+
*/
|
|
69
|
+
invocationRoleArn: string;
|
|
70
|
+
/**
|
|
71
|
+
* The execution account's artifacts bucket; the Harbour-side stage-package Lambda writes scan-sources/… into it through the invoke role, and the scanner writes scan-evidence/… beside it.
|
|
72
|
+
*/
|
|
73
|
+
artifactsBucket: string;
|
|
74
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Decision produced by the Isomorph Security Assurance machine
|
|
2
|
+
* Decision produced by the Isomorph Security Assurance machine. `outcome: BLOCKED` surfaces to callers as the registered non-retryable `gate.security-scan` error category; `reason` is present exactly when BLOCKED. A BLOCKED verdict is the output of a successful execution; a stage that crashes fails the execution and produces no verdict. The S3 evidence object named by `evidenceRef` is the full record — in-payload findings may be truncated.
|
|
3
3
|
*/
|
|
4
4
|
export interface SecurityVerdict {
|
|
5
5
|
/**
|
|
@@ -7,11 +7,11 @@ export interface SecurityVerdict {
|
|
|
7
7
|
*/
|
|
8
8
|
outcome: 'PASS' | 'BLOCKED';
|
|
9
9
|
/**
|
|
10
|
-
* Policy profile the evidence was evaluated against
|
|
10
|
+
* Policy profile the evidence was evaluated against: the input's `profile` when the caller named one, else derived from the input classification, else STANDARD.
|
|
11
11
|
*/
|
|
12
12
|
profile: 'BASELINE' | 'STANDARD' | 'HIGH' | 'CRITICAL';
|
|
13
13
|
/**
|
|
14
|
-
* Human-readable cause, present when outcome is BLOCKED
|
|
14
|
+
* Human-readable cause, present when outcome is BLOCKED: the sentence of the first policy rule that fired.
|
|
15
15
|
*/
|
|
16
16
|
reason?: string;
|
|
17
17
|
/**
|
|
@@ -25,7 +25,7 @@ export interface SecurityVerdict {
|
|
|
25
25
|
}
|
|
26
26
|
export interface ScanEvidence {
|
|
27
27
|
/**
|
|
28
|
-
* UNAVAILABLE
|
|
28
|
+
* What the tool reported, not whether it blocks (each finding's `blocking` says that): PASS when it found nothing, including when there was nothing to scan (no dependencies declared); FAIL when it has findings; UNAVAILABLE when the tool did not run or did not produce parseable output, which policy treats as blocking for required categories.
|
|
29
29
|
*/
|
|
30
30
|
status: 'PASS' | 'FAIL' | 'UNAVAILABLE';
|
|
31
31
|
/**
|
|
@@ -62,14 +62,30 @@ export interface Finding {
|
|
|
62
62
|
* Suggested fix, when the tool provides one.
|
|
63
63
|
*/
|
|
64
64
|
remediation?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Dependency name, for a dependency-sca finding.
|
|
67
|
+
*/
|
|
68
|
+
package?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Installed version of `package` the vulnerability applies to.
|
|
71
|
+
*/
|
|
72
|
+
installedVersion?: string;
|
|
73
|
+
/**
|
|
74
|
+
* First version of `package` that fixes the vulnerability, when the tool knows one.
|
|
75
|
+
*/
|
|
76
|
+
fixedVersion?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Set by policy on every finding it evaluated: true when the finding on its own fires a block rule under the evaluated profile, false when it is reported only.
|
|
79
|
+
*/
|
|
80
|
+
blocking?: boolean;
|
|
65
81
|
}
|
|
66
82
|
export interface EvidenceRef {
|
|
67
83
|
/**
|
|
68
|
-
* S3 bucket holding the full evidence object.
|
|
84
|
+
* S3 bucket holding the full evidence object; for a package scan, the artifacts bucket of the execution account the scanner ran in.
|
|
69
85
|
*/
|
|
70
86
|
bucket: string;
|
|
71
87
|
/**
|
|
72
|
-
* S3 key of the full evidence object, e.g.
|
|
88
|
+
* S3 key of the full evidence object, e.g. scan-evidence/<org>/<app>/<sourceDigest-hex>/<executionName>/evidence.json for a package scan.
|
|
73
89
|
*/
|
|
74
90
|
key: string;
|
|
75
91
|
}
|
|
@@ -77,11 +93,12 @@ export interface Provenance {
|
|
|
77
93
|
org: string;
|
|
78
94
|
app: string;
|
|
79
95
|
env: 'preview' | 'prod';
|
|
80
|
-
repo: string;
|
|
81
|
-
commit: string;
|
|
82
|
-
branch: string;
|
|
83
96
|
/**
|
|
84
|
-
*
|
|
97
|
+
* Tree digest of the scanned source (`sourceDigestOf`, `sha256:`-prefixed), echoed from the scan input's package block. Present for a package scan. Never compared with `snapshotSha256`, which hashes the zip bytes.
|
|
98
|
+
*/
|
|
99
|
+
sourceDigest?: string;
|
|
100
|
+
/**
|
|
101
|
+
* SHA-256 of the exact bytes that were extracted and scanned (the package zip for a package scan), verified before extraction. Bare hex.
|
|
85
102
|
*/
|
|
86
103
|
snapshotSha256: string;
|
|
87
104
|
/**
|
|
@@ -93,7 +110,11 @@ export interface Provenance {
|
|
|
93
110
|
*/
|
|
94
111
|
toolManifestDigest: string;
|
|
95
112
|
/**
|
|
96
|
-
*
|
|
113
|
+
* Orderable release version of the runner image that produced the evidence. Governance compares its numeric core with MINIMUM_SCANNER_VERSION to decide whether a PASS still counts.
|
|
114
|
+
*/
|
|
115
|
+
scannerVersion: string;
|
|
116
|
+
/**
|
|
117
|
+
* True iff the input named neither a profile nor a classification and the machine assumed STANDARD (decision 2026-08-27). An invalid classification fails closed and never reaches a verdict.
|
|
97
118
|
*/
|
|
98
119
|
classificationDefaulted: boolean;
|
|
99
120
|
}
|
|
@@ -112,6 +112,12 @@ export interface AiPolicyModel {
|
|
|
112
112
|
)[];
|
|
113
113
|
approved: boolean;
|
|
114
114
|
pricing: AiPolicyPricing;
|
|
115
|
+
/**
|
|
116
|
+
* What the development kit can do with this model through the Gateway, declared by the tenant for a model it adds beyond the Isomorph catalogue (ADR 0015). Absent keeps the earlier vendor-derived answers; an empty list declares none. Governance ignores it on a catalogue model and caps kitSdkCompatible, streaming and imageEdit by the vendor. The Gateway does not read it.
|
|
117
|
+
*
|
|
118
|
+
* @maxItems 5
|
|
119
|
+
*/
|
|
120
|
+
features?: ('kitSdkCompatible' | 'toolCalling' | 'streaming' | 'imageInput' | 'imageEdit')[];
|
|
115
121
|
}
|
|
116
122
|
export interface AiPolicyPricing {
|
|
117
123
|
revision: AiPolicyIdentifier;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/* eslint-disable */
|
|
2
2
|
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
3
|
|
|
4
|
-
export const ContractRepositoryVersion = "0.
|
|
5
|
-
export const ContractPublishVersion = "0.
|
|
6
|
-
export const ContractPublishTag = "v0.
|
|
7
|
-
export const ContractSchemasDigest = "sha256:
|
|
4
|
+
export const ContractRepositoryVersion = "0.68.0.0" as const;
|
|
5
|
+
export const ContractPublishVersion = "0.68.0" as const;
|
|
6
|
+
export const ContractPublishTag = "v0.68.0" as const;
|
|
7
|
+
export const ContractSchemasDigest = "sha256:3860585b4a4a55334e788faca34018dfaa21bf7ee5fa42bb50b0a454a77047b3" as const;
|
|
8
8
|
export const ContractAiFixturesDigest = "sha256:edac31c92e146ca1c40130f2fb5649db82e24b8cd1ac758153b90612052fddb6" as const;
|
|
9
|
-
export const ContractGeneratedGoDigest = "sha256:
|
|
10
|
-
export const ContractGeneratedTypeScriptDigest = "sha256:
|
|
9
|
+
export const ContractGeneratedGoDigest = "sha256:0c97fd145737bf8fba6de780187033f04e52fe524284cd95c084fcda38e31a28" as const;
|
|
10
|
+
export const ContractGeneratedTypeScriptDigest = "sha256:bd9927f250e96a91958f078ea29d1420ca3d6545ce93b2b2901033ac09e52827" as const;
|
package/gen-ts/index.ts
CHANGED
|
@@ -62,7 +62,7 @@ export * from './saas-connection.js';
|
|
|
62
62
|
export * from './sanitized-binding-digest-helper.js';
|
|
63
63
|
export * from './sanitized-binding-evidence.js';
|
|
64
64
|
export * from './secret-reference.js';
|
|
65
|
-
export * from './security-scan-input.js';
|
|
65
|
+
export * from './security-scan-input-v2.js';
|
|
66
66
|
export * from './security-verdict.js';
|
|
67
67
|
export * from './transform-parked-result.js';
|
|
68
68
|
export * from './transform-report.js';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Input to the Security Assurance machine, second shape, replacing security-scan-input.schema.json. V1 scanned a deployed commit located through the deployment state; v2 scans exactly one thing: an uploaded package that governance validated at source intake, identified by the zip sha256 the stager verifies before extraction and by the tree digest governance computed from the unzipped bytes (`sourceDigestOf`, `sha256:`-prefixed), which keys the governance scan record and the check report on the laptop. Commit-mode and ARTIFACT-phase inputs are deliberately absent: the console's later on-demand scan uses this same package path against the deploy upload, and the Transform lane runs the scanner in-process; an image scan, if it returns, is an additive v3. The policy profile is named by the caller when it knows better than the data classification (the kit lane names BASELINE); `profile` and `classification` are mutually exclusive, and both absent still defaults to STANDARD with `classificationDefaulted: true`. Nothing here carries a scanner version: the scanner stamps its own into verdict provenance, and governance decides validity by comparing that against its MINIMUM_SCANNER_VERSION. `org`/`app` are the tenant and app ids for kit apps; `env` stays required because the evidence key carries it (governance passes `preview` for a package scan; promotion never re-scans). The `execution` block names the tenant's execution-account scanner, invoke role and artifacts bucket, resolved by governance the way admission resolves them for the deploy machine.
|
|
6
|
+
*/
|
|
7
|
+
export interface SecurityScanInputV2 {
|
|
8
|
+
schema: 'harbour.security-scan-input/2.0';
|
|
9
|
+
/**
|
|
10
|
+
* Isomorph organization id (the governance tenant id for kit apps), e.g. fourier.
|
|
11
|
+
*/
|
|
12
|
+
org: string;
|
|
13
|
+
/**
|
|
14
|
+
* Isomorph app id within the org (the governance appId for kit apps).
|
|
15
|
+
*/
|
|
16
|
+
app: string;
|
|
17
|
+
/**
|
|
18
|
+
* Evidence-key segment and provenance only; governance passes `preview` for a package scan.
|
|
19
|
+
*/
|
|
20
|
+
env: 'preview' | 'prod';
|
|
21
|
+
package: PackageSource;
|
|
22
|
+
execution: Execution;
|
|
23
|
+
/**
|
|
24
|
+
* Policy profile named by the caller. Takes the place of deriving one from `classification`; the verdict echoes the profile evaluated and stamps `classificationDefaulted: false`. Governance names BASELINE for kit-lane scans; the default when nothing is named is STANDARD.
|
|
25
|
+
*/
|
|
26
|
+
profile?: 'BASELINE' | 'STANDARD' | 'HIGH' | 'CRITICAL';
|
|
27
|
+
/**
|
|
28
|
+
* Data classification, mapped to a profile as in v1 (GREEN → BASELINE, YELLOW → STANDARD, ORANGE → HIGH, RED → CRITICAL). Not allowed beside `profile`. Absent with no `profile` means STANDARD and `classificationDefaulted: true`; an invalid value fails closed.
|
|
29
|
+
*/
|
|
30
|
+
classification?: 'GREEN' | 'YELLOW' | 'ORANGE' | 'RED';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The bytes `isomorph secure` (or a later console re-run against a deploy upload) put through source intake.
|
|
34
|
+
*/
|
|
35
|
+
export interface PackageSource {
|
|
36
|
+
/**
|
|
37
|
+
* Bucket holding the uploaded package zip (the governance upload bucket; the stage-package role holds a prefix-scoped read grant and the key's decrypt).
|
|
38
|
+
*/
|
|
39
|
+
bucket: string;
|
|
40
|
+
/**
|
|
41
|
+
* Object key of the package zip as the completed multipart upload left it, under the `scan/` prefix.
|
|
42
|
+
*/
|
|
43
|
+
key: string;
|
|
44
|
+
/**
|
|
45
|
+
* S3 object version to read, when the bucket is versioned, so a later re-upload under the same key cannot change what was scanned.
|
|
46
|
+
*/
|
|
47
|
+
versionId?: string;
|
|
48
|
+
/**
|
|
49
|
+
* SHA-256 of the zip bytes. The stager verifies it before extraction and it becomes the verdict's `snapshotSha256`. Governance already checked it equals the manifest's packageSha256 at intake.
|
|
50
|
+
*/
|
|
51
|
+
sha256: string;
|
|
52
|
+
/**
|
|
53
|
+
* Tree digest governance computed from the unzipped, validated package with the shared source-digest algorithm, `sha256:` prefixed as `sourceDigestOf` emits it (the same value `isomorph check` pins in check-report.json). Caller-supplied provenance echoed into the verdict; the scan record and the deploy gate are keyed by it.
|
|
54
|
+
*/
|
|
55
|
+
sourceDigest: string;
|
|
56
|
+
/**
|
|
57
|
+
* Digest of the file manifest the CLI sent, for the evidence record. Provenance only.
|
|
58
|
+
*/
|
|
59
|
+
manifestDigest?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Where the scan runs. The machine passes the function ARN and role to its one execution-account task as FunctionName and Credentials.RoleArn, exactly as the deploy machine does with its execution block.
|
|
63
|
+
*/
|
|
64
|
+
export interface Execution {
|
|
65
|
+
/**
|
|
66
|
+
* The tenant's execution-account security-scan Lambda.
|
|
67
|
+
*/
|
|
68
|
+
securityScanFunctionArn: string;
|
|
69
|
+
/**
|
|
70
|
+
* Role the machine assumes to invoke the scanner and the Harbour-side stage-package Lambda assumes to write the staged zip (harbour-preview-v2-invoke in beta).
|
|
71
|
+
*/
|
|
72
|
+
invocationRoleArn: string;
|
|
73
|
+
/**
|
|
74
|
+
* The execution account's artifacts bucket; the Harbour-side stage-package Lambda writes scan-sources/… into it through the invoke role, and the scanner writes scan-evidence/… beside it.
|
|
75
|
+
*/
|
|
76
|
+
artifactsBucket: string;
|
|
77
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Decision produced by the Isomorph Security Assurance machine
|
|
5
|
+
* Decision produced by the Isomorph Security Assurance machine. `outcome: BLOCKED` surfaces to callers as the registered non-retryable `gate.security-scan` error category; `reason` is present exactly when BLOCKED. A BLOCKED verdict is the output of a successful execution; a stage that crashes fails the execution and produces no verdict. The S3 evidence object named by `evidenceRef` is the full record — in-payload findings may be truncated.
|
|
6
6
|
*/
|
|
7
7
|
export interface SecurityVerdict {
|
|
8
8
|
/**
|
|
@@ -10,11 +10,11 @@ export interface SecurityVerdict {
|
|
|
10
10
|
*/
|
|
11
11
|
outcome: 'PASS' | 'BLOCKED';
|
|
12
12
|
/**
|
|
13
|
-
* Policy profile the evidence was evaluated against
|
|
13
|
+
* Policy profile the evidence was evaluated against: the input's `profile` when the caller named one, else derived from the input classification, else STANDARD.
|
|
14
14
|
*/
|
|
15
15
|
profile: 'BASELINE' | 'STANDARD' | 'HIGH' | 'CRITICAL';
|
|
16
16
|
/**
|
|
17
|
-
* Human-readable cause, present when outcome is BLOCKED
|
|
17
|
+
* Human-readable cause, present when outcome is BLOCKED: the sentence of the first policy rule that fired.
|
|
18
18
|
*/
|
|
19
19
|
reason?: string;
|
|
20
20
|
/**
|
|
@@ -28,7 +28,7 @@ export interface SecurityVerdict {
|
|
|
28
28
|
}
|
|
29
29
|
export interface ScanEvidence {
|
|
30
30
|
/**
|
|
31
|
-
* UNAVAILABLE
|
|
31
|
+
* What the tool reported, not whether it blocks (each finding's `blocking` says that): PASS when it found nothing, including when there was nothing to scan (no dependencies declared); FAIL when it has findings; UNAVAILABLE when the tool did not run or did not produce parseable output, which policy treats as blocking for required categories.
|
|
32
32
|
*/
|
|
33
33
|
status: 'PASS' | 'FAIL' | 'UNAVAILABLE';
|
|
34
34
|
/**
|
|
@@ -65,14 +65,30 @@ export interface Finding {
|
|
|
65
65
|
* Suggested fix, when the tool provides one.
|
|
66
66
|
*/
|
|
67
67
|
remediation?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Dependency name, for a dependency-sca finding.
|
|
70
|
+
*/
|
|
71
|
+
package?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Installed version of `package` the vulnerability applies to.
|
|
74
|
+
*/
|
|
75
|
+
installedVersion?: string;
|
|
76
|
+
/**
|
|
77
|
+
* First version of `package` that fixes the vulnerability, when the tool knows one.
|
|
78
|
+
*/
|
|
79
|
+
fixedVersion?: string;
|
|
80
|
+
/**
|
|
81
|
+
* Set by policy on every finding it evaluated: true when the finding on its own fires a block rule under the evaluated profile, false when it is reported only.
|
|
82
|
+
*/
|
|
83
|
+
blocking?: boolean;
|
|
68
84
|
}
|
|
69
85
|
export interface EvidenceRef {
|
|
70
86
|
/**
|
|
71
|
-
* S3 bucket holding the full evidence object.
|
|
87
|
+
* S3 bucket holding the full evidence object; for a package scan, the artifacts bucket of the execution account the scanner ran in.
|
|
72
88
|
*/
|
|
73
89
|
bucket: string;
|
|
74
90
|
/**
|
|
75
|
-
* S3 key of the full evidence object, e.g.
|
|
91
|
+
* S3 key of the full evidence object, e.g. scan-evidence/<org>/<app>/<sourceDigest-hex>/<executionName>/evidence.json for a package scan.
|
|
76
92
|
*/
|
|
77
93
|
key: string;
|
|
78
94
|
}
|
|
@@ -80,11 +96,12 @@ export interface Provenance {
|
|
|
80
96
|
org: string;
|
|
81
97
|
app: string;
|
|
82
98
|
env: 'preview' | 'prod';
|
|
83
|
-
repo: string;
|
|
84
|
-
commit: string;
|
|
85
|
-
branch: string;
|
|
86
99
|
/**
|
|
87
|
-
*
|
|
100
|
+
* Tree digest of the scanned source (`sourceDigestOf`, `sha256:`-prefixed), echoed from the scan input's package block. Present for a package scan. Never compared with `snapshotSha256`, which hashes the zip bytes.
|
|
101
|
+
*/
|
|
102
|
+
sourceDigest?: string;
|
|
103
|
+
/**
|
|
104
|
+
* SHA-256 of the exact bytes that were extracted and scanned (the package zip for a package scan), verified before extraction. Bare hex.
|
|
88
105
|
*/
|
|
89
106
|
snapshotSha256: string;
|
|
90
107
|
/**
|
|
@@ -96,7 +113,11 @@ export interface Provenance {
|
|
|
96
113
|
*/
|
|
97
114
|
toolManifestDigest: string;
|
|
98
115
|
/**
|
|
99
|
-
*
|
|
116
|
+
* Orderable release version of the runner image that produced the evidence. Governance compares its numeric core with MINIMUM_SCANNER_VERSION to decide whether a PASS still counts.
|
|
117
|
+
*/
|
|
118
|
+
scannerVersion: string;
|
|
119
|
+
/**
|
|
120
|
+
* True iff the input named neither a profile nor a classification and the machine assumed STANDARD (decision 2026-08-27). An invalid classification fails closed and never reaches a verdict.
|
|
100
121
|
*/
|
|
101
122
|
classificationDefaulted: boolean;
|
|
102
123
|
}
|
package/package.json
CHANGED
|
@@ -159,7 +159,14 @@
|
|
|
159
159
|
"items": { "type": "string", "enum": ["generation", "embeddings", "transcription", "translation", "speech", "image", "video", "realtime"] }
|
|
160
160
|
},
|
|
161
161
|
"approved": { "type": "boolean" },
|
|
162
|
-
"pricing": { "$ref": "#/definitions/AiPolicyPricing" }
|
|
162
|
+
"pricing": { "$ref": "#/definitions/AiPolicyPricing" },
|
|
163
|
+
"features": {
|
|
164
|
+
"type": "array",
|
|
165
|
+
"maxItems": 5,
|
|
166
|
+
"uniqueItems": true,
|
|
167
|
+
"items": { "type": "string", "enum": ["kitSdkCompatible", "toolCalling", "streaming", "imageInput", "imageEdit"] },
|
|
168
|
+
"description": "What the development kit can do with this model through the Gateway, declared by the tenant for a model it adds beyond the Isomorph catalogue (ADR 0015). Absent keeps the earlier vendor-derived answers; an empty list declares none. Governance ignores it on a catalogue model and caps kitSdkCompatible, streaming and imageEdit by the vendor. The Gateway does not read it."
|
|
169
|
+
}
|
|
163
170
|
}
|
|
164
171
|
},
|
|
165
172
|
"AiPolicyRouteTarget": {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://schemas.harbour.dev/security-scan-input-v2.schema.json",
|
|
4
|
+
"title": "SecurityScanInputV2",
|
|
5
|
+
"description": "Input to the Security Assurance machine, second shape, replacing security-scan-input.schema.json. V1 scanned a deployed commit located through the deployment state; v2 scans exactly one thing: an uploaded package that governance validated at source intake, identified by the zip sha256 the stager verifies before extraction and by the tree digest governance computed from the unzipped bytes (`sourceDigestOf`, `sha256:`-prefixed), which keys the governance scan record and the check report on the laptop. Commit-mode and ARTIFACT-phase inputs are deliberately absent: the console's later on-demand scan uses this same package path against the deploy upload, and the Transform lane runs the scanner in-process; an image scan, if it returns, is an additive v3. The policy profile is named by the caller when it knows better than the data classification (the kit lane names BASELINE); `profile` and `classification` are mutually exclusive, and both absent still defaults to STANDARD with `classificationDefaulted: true`. Nothing here carries a scanner version: the scanner stamps its own into verdict provenance, and governance decides validity by comparing that against its MINIMUM_SCANNER_VERSION. `org`/`app` are the tenant and app ids for kit apps; `env` stays required because the evidence key carries it (governance passes `preview` for a package scan; promotion never re-scans). The `execution` block names the tenant's execution-account scanner, invoke role and artifacts bucket, resolved by governance the way admission resolves them for the deploy machine.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["schema", "org", "app", "env", "package", "execution"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"schema": { "type": "string", "const": "harbour.security-scan-input/2.0" },
|
|
11
|
+
"org": { "type": "string", "minLength": 1, "description": "Isomorph organization id (the governance tenant id for kit apps), e.g. fourier." },
|
|
12
|
+
"app": { "type": "string", "minLength": 1, "description": "Isomorph app id within the org (the governance appId for kit apps)." },
|
|
13
|
+
"env": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"enum": ["preview", "prod"],
|
|
16
|
+
"description": "Evidence-key segment and provenance only; governance passes `preview` for a package scan."
|
|
17
|
+
},
|
|
18
|
+
"package": { "$ref": "#/definitions/PackageSource" },
|
|
19
|
+
"execution": { "$ref": "#/definitions/Execution" },
|
|
20
|
+
"profile": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": ["BASELINE", "STANDARD", "HIGH", "CRITICAL"],
|
|
23
|
+
"description": "Policy profile named by the caller. Takes the place of deriving one from `classification`; the verdict echoes the profile evaluated and stamps `classificationDefaulted: false`. Governance names BASELINE for kit-lane scans; the default when nothing is named is STANDARD."
|
|
24
|
+
},
|
|
25
|
+
"classification": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"enum": ["GREEN", "YELLOW", "ORANGE", "RED"],
|
|
28
|
+
"description": "Data classification, mapped to a profile as in v1 (GREEN → BASELINE, YELLOW → STANDARD, ORANGE → HIGH, RED → CRITICAL). Not allowed beside `profile`. Absent with no `profile` means STANDARD and `classificationDefaulted: true`; an invalid value fails closed."
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"not": { "required": ["profile", "classification"] },
|
|
32
|
+
"definitions": {
|
|
33
|
+
"PackageSource": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"additionalProperties": false,
|
|
36
|
+
"required": ["bucket", "key", "sha256", "sourceDigest"],
|
|
37
|
+
"properties": {
|
|
38
|
+
"bucket": { "type": "string", "minLength": 1, "description": "Bucket holding the uploaded package zip (the governance upload bucket; the stage-package role holds a prefix-scoped read grant and the key's decrypt)." },
|
|
39
|
+
"key": { "type": "string", "minLength": 1, "description": "Object key of the package zip as the completed multipart upload left it, under the `scan/` prefix." },
|
|
40
|
+
"versionId": { "type": "string", "minLength": 1, "description": "S3 object version to read, when the bucket is versioned, so a later re-upload under the same key cannot change what was scanned." },
|
|
41
|
+
"sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "SHA-256 of the zip bytes. The stager verifies it before extraction and it becomes the verdict's `snapshotSha256`. Governance already checked it equals the manifest's packageSha256 at intake." },
|
|
42
|
+
"sourceDigest": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$", "description": "Tree digest governance computed from the unzipped, validated package with the shared source-digest algorithm, `sha256:` prefixed as `sourceDigestOf` emits it (the same value `isomorph check` pins in check-report.json). Caller-supplied provenance echoed into the verdict; the scan record and the deploy gate are keyed by it." },
|
|
43
|
+
"manifestDigest": { "type": "string", "pattern": "^[0-9a-f]{64}$", "description": "Digest of the file manifest the CLI sent, for the evidence record. Provenance only." }
|
|
44
|
+
},
|
|
45
|
+
"description": "The bytes `isomorph secure` (or a later console re-run against a deploy upload) put through source intake."
|
|
46
|
+
},
|
|
47
|
+
"Execution": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": false,
|
|
50
|
+
"required": ["securityScanFunctionArn", "invocationRoleArn", "artifactsBucket"],
|
|
51
|
+
"properties": { "securityScanFunctionArn": { "type": "string", "pattern": "^arn:aws:lambda:", "description": "The tenant's execution-account security-scan Lambda." },
|
|
52
|
+
"invocationRoleArn": { "type": "string", "pattern": "^arn:aws:iam::", "description": "Role the machine assumes to invoke the scanner and the Harbour-side stage-package Lambda assumes to write the staged zip (harbour-preview-v2-invoke in beta)." },
|
|
53
|
+
"artifactsBucket": { "type": "string", "minLength": 1, "description": "The execution account's artifacts bucket; the Harbour-side stage-package Lambda writes scan-sources/… into it through the invoke role, and the scanner writes scan-evidence/… beside it." }
|
|
54
|
+
},
|
|
55
|
+
"description": "Where the scan runs. The machine passes the function ARN and role to its one execution-account task as FunctionName and Credentials.RoleArn, exactly as the deploy machine does with its execution block."
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"examples": [
|
|
59
|
+
{
|
|
60
|
+
"schema": "harbour.security-scan-input/2.0",
|
|
61
|
+
"org": "fourier",
|
|
62
|
+
"app": "app-1f2e3d4c",
|
|
63
|
+
"env": "preview",
|
|
64
|
+
"package": {
|
|
65
|
+
"bucket": "harbour-governance-source-uploads",
|
|
66
|
+
"key": "scan/fourier/app-1f2e3d4c/scan-01J9Q8ZT4M6K7Q3R8V5X2N1P0W/package.zip",
|
|
67
|
+
"versionId": "3HL4kqtJlcpXroDTDmJ+rmSpXd3dIbrHY+MTRCxf3vjVBH40Nr8X8gdRQBpUMLUo",
|
|
68
|
+
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
|
|
69
|
+
"sourceDigest": "sha256:2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
|
|
70
|
+
"manifestDigest": "fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9"
|
|
71
|
+
},
|
|
72
|
+
"execution": { "securityScanFunctionArn": "arn:aws:lambda:us-east-1:195236889504:function:harbour-preview-v2-security-scan",
|
|
73
|
+
"invocationRoleArn": "arn:aws:iam::195236889504:role/harbour-preview-v2-invoke",
|
|
74
|
+
"artifactsBucket": "harbour-preview-v2-artifacts-195236889504"
|
|
75
|
+
},
|
|
76
|
+
"profile": "BASELINE"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
3
|
"$id": "https://schemas.harbour.dev/security-verdict.schema.json",
|
|
4
4
|
"title": "SecurityVerdict",
|
|
5
|
-
"description": "Decision produced by the Isomorph Security Assurance machine
|
|
5
|
+
"description": "Decision produced by the Isomorph Security Assurance machine. `outcome: BLOCKED` surfaces to callers as the registered non-retryable `gate.security-scan` error category; `reason` is present exactly when BLOCKED. A BLOCKED verdict is the output of a successful execution; a stage that crashes fails the execution and produces no verdict. The S3 evidence object named by `evidenceRef` is the full record — in-payload findings may be truncated.",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
|
8
8
|
"required": ["outcome", "profile", "evidence", "evidenceRef", "provenance"],
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
"profile": {
|
|
16
16
|
"type": "string",
|
|
17
17
|
"enum": ["BASELINE", "STANDARD", "HIGH", "CRITICAL"],
|
|
18
|
-
"description": "Policy profile the evidence was evaluated against
|
|
18
|
+
"description": "Policy profile the evidence was evaluated against: the input's `profile` when the caller named one, else derived from the input classification, else STANDARD."
|
|
19
19
|
},
|
|
20
20
|
"reason": {
|
|
21
21
|
"type": "string",
|
|
22
22
|
"minLength": 1,
|
|
23
|
-
"description": "Human-readable cause, present when outcome is BLOCKED
|
|
23
|
+
"description": "Human-readable cause, present when outcome is BLOCKED: the sentence of the first policy rule that fired."
|
|
24
24
|
},
|
|
25
25
|
"evidence": {
|
|
26
26
|
"type": "object",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"status": {
|
|
40
40
|
"type": "string",
|
|
41
41
|
"enum": ["PASS", "FAIL", "UNAVAILABLE"],
|
|
42
|
-
"description": "UNAVAILABLE
|
|
42
|
+
"description": "What the tool reported, not whether it blocks (each finding's `blocking` says that): PASS when it found nothing, including when there was nothing to scan (no dependencies declared); FAIL when it has findings; UNAVAILABLE when the tool did not run or did not produce parseable output, which policy treats as blocking for required categories."
|
|
43
43
|
},
|
|
44
44
|
"findings": {
|
|
45
45
|
"type": "array",
|
|
@@ -59,7 +59,11 @@
|
|
|
59
59
|
"path": { "type": "string", "description": "Repository-relative file path, when the finding is file-anchored." },
|
|
60
60
|
"line": { "type": "integer", "minimum": 1, "description": "1-based line number, when the finding is line-anchored." },
|
|
61
61
|
"message": { "type": "string", "minLength": 1, "description": "Human-readable finding description. Secret values are never included — only locations." },
|
|
62
|
-
"remediation": { "type": "string", "description": "Suggested fix, when the tool provides one." }
|
|
62
|
+
"remediation": { "type": "string", "description": "Suggested fix, when the tool provides one." },
|
|
63
|
+
"package": { "type": "string", "minLength": 1, "description": "Dependency name, for a dependency-sca finding." },
|
|
64
|
+
"installedVersion": { "type": "string", "minLength": 1, "description": "Installed version of `package` the vulnerability applies to." },
|
|
65
|
+
"fixedVersion": { "type": "string", "minLength": 1, "description": "First version of `package` that fixes the vulnerability, when the tool knows one." },
|
|
66
|
+
"blocking": { "type": "boolean", "description": "Set by policy on every finding it evaluated: true when the finding on its own fires a block rule under the evaluated profile, false when it is reported only." }
|
|
63
67
|
}
|
|
64
68
|
},
|
|
65
69
|
"EvidenceRef": {
|
|
@@ -67,34 +71,41 @@
|
|
|
67
71
|
"additionalProperties": false,
|
|
68
72
|
"required": ["bucket", "key"],
|
|
69
73
|
"properties": {
|
|
70
|
-
"bucket": { "type": "string", "minLength": 1, "description": "S3 bucket holding the full evidence object." },
|
|
71
|
-
"key": { "type": "string", "minLength": 1, "description": "S3 key of the full evidence object, e.g.
|
|
74
|
+
"bucket": { "type": "string", "minLength": 1, "description": "S3 bucket holding the full evidence object; for a package scan, the artifacts bucket of the execution account the scanner ran in." },
|
|
75
|
+
"key": { "type": "string", "minLength": 1, "description": "S3 key of the full evidence object, e.g. scan-evidence/<org>/<app>/<sourceDigest-hex>/<executionName>/evidence.json for a package scan." }
|
|
72
76
|
}
|
|
73
77
|
},
|
|
74
78
|
"Provenance": {
|
|
75
79
|
"type": "object",
|
|
76
80
|
"additionalProperties": false,
|
|
77
|
-
"required": ["org", "app", "env", "
|
|
81
|
+
"required": ["org", "app", "env", "snapshotSha256", "scannedAt", "toolManifestDigest", "scannerVersion", "classificationDefaulted"],
|
|
78
82
|
"properties": {
|
|
79
83
|
"org": { "type": "string", "minLength": 1 },
|
|
80
84
|
"app": { "type": "string", "minLength": 1 },
|
|
81
85
|
"env": { "type": "string", "enum": ["preview", "prod"] },
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
"sourceDigest": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"pattern": "^sha256:[0-9a-f]{64}$",
|
|
89
|
+
"description": "Tree digest of the scanned source (`sourceDigestOf`, `sha256:`-prefixed), echoed from the scan input's package block. Present for a package scan. Never compared with `snapshotSha256`, which hashes the zip bytes."
|
|
90
|
+
},
|
|
85
91
|
"snapshotSha256": {
|
|
86
92
|
"type": "string",
|
|
87
93
|
"pattern": "^[0-9a-f]{64}$",
|
|
88
|
-
"description": "SHA-256 of the exact
|
|
94
|
+
"description": "SHA-256 of the exact bytes that were extracted and scanned (the package zip for a package scan), verified before extraction. Bare hex."
|
|
89
95
|
},
|
|
90
96
|
"scannedAt": { "type": "string", "format": "date-time", "description": "UTC timestamp the scan completed." },
|
|
91
97
|
"toolManifestDigest": {
|
|
92
98
|
"type": "string",
|
|
93
99
|
"description": "Digest of the runner image's tool-manifest.json — pins which tool versions produced this evidence."
|
|
94
100
|
},
|
|
101
|
+
"scannerVersion": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"pattern": "^v?\\d+\\.\\d+\\.\\d+(?:[-+].*)?$",
|
|
104
|
+
"description": "Orderable release version of the runner image that produced the evidence. Governance compares its numeric core with MINIMUM_SCANNER_VERSION to decide whether a PASS still counts."
|
|
105
|
+
},
|
|
95
106
|
"classificationDefaulted": {
|
|
96
107
|
"type": "boolean",
|
|
97
|
-
"description": "True iff the input
|
|
108
|
+
"description": "True iff the input named neither a profile nor a classification and the machine assumed STANDARD (decision 2026-08-27). An invalid classification fails closed and never reaches a verdict."
|
|
98
109
|
}
|
|
99
110
|
}
|
|
100
111
|
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Input to the Isomorph Security Assurance machine (Security Assurance LLD §2). SOURCE (M1) scans an ingested commit; ARTIFACT (M2) scans built outputs — a container image digest, a deployable bundle, and/or synthesized infrastructure — named directly by the caller. `commit` is the identity being scanned; `org/app/env` locate the snapshot (the control-state table has no commit GSI, so a bare commit is not resolvable); `branch` is caller-supplied provenance. When phase is ARTIFACT at least one of `imageDigest`, `bundleRef`, or `infraRefs` must be present.
|
|
3
|
-
*/
|
|
4
|
-
export interface SecurityScanInput {
|
|
5
|
-
/**
|
|
6
|
-
* Scan phase. SOURCE (M1) scans the ingested snapshot for the commit; ARTIFACT (M2) scans built outputs named by imageDigest/bundleRef/infraRefs — at least one of which must be present.
|
|
7
|
-
*/
|
|
8
|
-
phase: 'SOURCE' | 'ARTIFACT';
|
|
9
|
-
/**
|
|
10
|
-
* Isomorph organization id, e.g. fourier.
|
|
11
|
-
*/
|
|
12
|
-
org: string;
|
|
13
|
-
/**
|
|
14
|
-
* Isomorph app id within the org, e.g. focuslist.
|
|
15
|
-
*/
|
|
16
|
-
app: string;
|
|
17
|
-
/**
|
|
18
|
-
* Environment whose ingested snapshots are searched for the commit. M1 deploys preview-only; prod is contract-stable for M3.
|
|
19
|
-
*/
|
|
20
|
-
env: 'preview' | 'prod';
|
|
21
|
-
/**
|
|
22
|
-
* GitHub owner/name of the source repository, e.g. Fourier-Labs-AI/focus-list.
|
|
23
|
-
*/
|
|
24
|
-
repo: string;
|
|
25
|
-
/**
|
|
26
|
-
* Full 40-hex lowercase commit SHA — the identity being scanned.
|
|
27
|
-
*/
|
|
28
|
-
commit: string;
|
|
29
|
-
/**
|
|
30
|
-
* Branch name, supplied authoritatively by the caller in v1 (provenance only — never used for resolution).
|
|
31
|
-
*/
|
|
32
|
-
branch: string;
|
|
33
|
-
/**
|
|
34
|
-
* Data classification of the app. Optional in v1 (decided 2026-08-27): when ABSENT the machine assumes the STANDARD profile and stamps classificationDefaulted: true in the verdict provenance. An invalid value still fails closed — only absence defaults. No classifier exists until M4; until then callers state it or accept the default.
|
|
35
|
-
*/
|
|
36
|
-
classification?: 'GREEN' | 'YELLOW' | 'ORANGE' | 'RED';
|
|
37
|
-
/**
|
|
38
|
-
* ARTIFACT phase: container image to scan, as either a digest-qualified ECR reference (<ecr-uri>@sha256:<64-hex>) or a bare sha256:<64-hex> digest. Digest-addressed only — tags are not accepted, so the scanned bytes are the deployed bytes.
|
|
39
|
-
*/
|
|
40
|
-
imageDigest?: string;
|
|
41
|
-
bundleRef?: S3Ref;
|
|
42
|
-
/**
|
|
43
|
-
* ARTIFACT phase: S3 locations of synthesized infrastructure documents (e.g. CloudFormation templates) evaluated by policy (OPA/rego) checks.
|
|
44
|
-
*
|
|
45
|
-
* @minItems 1
|
|
46
|
-
*/
|
|
47
|
-
infraRefs?: S3Ref1[];
|
|
48
|
-
/**
|
|
49
|
-
* Optional build-source provenance for ARTIFACT calls where the top-level repo/commit describe the source of the build rather than the artifact itself; stamped into verdict provenance verbatim.
|
|
50
|
-
*/
|
|
51
|
-
provenance?: {
|
|
52
|
-
/**
|
|
53
|
-
* GitHub owner/name of the build-source repository.
|
|
54
|
-
*/
|
|
55
|
-
repo: string;
|
|
56
|
-
/**
|
|
57
|
-
* Full 40-hex lowercase commit SHA the artifact was built from.
|
|
58
|
-
*/
|
|
59
|
-
commit: string;
|
|
60
|
-
/**
|
|
61
|
-
* Branch the artifact was built from, caller-supplied provenance.
|
|
62
|
-
*/
|
|
63
|
-
branch?: string;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* ARTIFACT phase: S3 location of the built deployable bundle to scan.
|
|
68
|
-
*/
|
|
69
|
-
export interface S3Ref {
|
|
70
|
-
/**
|
|
71
|
-
* S3 bucket name.
|
|
72
|
-
*/
|
|
73
|
-
bucket: string;
|
|
74
|
-
/**
|
|
75
|
-
* S3 object key.
|
|
76
|
-
*/
|
|
77
|
-
key: string;
|
|
78
|
-
}
|
|
79
|
-
export interface S3Ref1 {
|
|
80
|
-
/**
|
|
81
|
-
* S3 bucket name.
|
|
82
|
-
*/
|
|
83
|
-
bucket: string;
|
|
84
|
-
/**
|
|
85
|
-
* S3 object key.
|
|
86
|
-
*/
|
|
87
|
-
key: string;
|
|
88
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
// Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Input to the Isomorph Security Assurance machine (Security Assurance LLD §2). SOURCE (M1) scans an ingested commit; ARTIFACT (M2) scans built outputs — a container image digest, a deployable bundle, and/or synthesized infrastructure — named directly by the caller. `commit` is the identity being scanned; `org/app/env` locate the snapshot (the control-state table has no commit GSI, so a bare commit is not resolvable); `branch` is caller-supplied provenance. When phase is ARTIFACT at least one of `imageDigest`, `bundleRef`, or `infraRefs` must be present.
|
|
6
|
-
*/
|
|
7
|
-
export interface SecurityScanInput {
|
|
8
|
-
/**
|
|
9
|
-
* Scan phase. SOURCE (M1) scans the ingested snapshot for the commit; ARTIFACT (M2) scans built outputs named by imageDigest/bundleRef/infraRefs — at least one of which must be present.
|
|
10
|
-
*/
|
|
11
|
-
phase: 'SOURCE' | 'ARTIFACT';
|
|
12
|
-
/**
|
|
13
|
-
* Isomorph organization id, e.g. fourier.
|
|
14
|
-
*/
|
|
15
|
-
org: string;
|
|
16
|
-
/**
|
|
17
|
-
* Isomorph app id within the org, e.g. focuslist.
|
|
18
|
-
*/
|
|
19
|
-
app: string;
|
|
20
|
-
/**
|
|
21
|
-
* Environment whose ingested snapshots are searched for the commit. M1 deploys preview-only; prod is contract-stable for M3.
|
|
22
|
-
*/
|
|
23
|
-
env: 'preview' | 'prod';
|
|
24
|
-
/**
|
|
25
|
-
* GitHub owner/name of the source repository, e.g. Fourier-Labs-AI/focus-list.
|
|
26
|
-
*/
|
|
27
|
-
repo: string;
|
|
28
|
-
/**
|
|
29
|
-
* Full 40-hex lowercase commit SHA — the identity being scanned.
|
|
30
|
-
*/
|
|
31
|
-
commit: string;
|
|
32
|
-
/**
|
|
33
|
-
* Branch name, supplied authoritatively by the caller in v1 (provenance only — never used for resolution).
|
|
34
|
-
*/
|
|
35
|
-
branch: string;
|
|
36
|
-
/**
|
|
37
|
-
* Data classification of the app. Optional in v1 (decided 2026-08-27): when ABSENT the machine assumes the STANDARD profile and stamps classificationDefaulted: true in the verdict provenance. An invalid value still fails closed — only absence defaults. No classifier exists until M4; until then callers state it or accept the default.
|
|
38
|
-
*/
|
|
39
|
-
classification?: 'GREEN' | 'YELLOW' | 'ORANGE' | 'RED';
|
|
40
|
-
/**
|
|
41
|
-
* ARTIFACT phase: container image to scan, as either a digest-qualified ECR reference (<ecr-uri>@sha256:<64-hex>) or a bare sha256:<64-hex> digest. Digest-addressed only — tags are not accepted, so the scanned bytes are the deployed bytes.
|
|
42
|
-
*/
|
|
43
|
-
imageDigest?: string;
|
|
44
|
-
bundleRef?: S3Ref;
|
|
45
|
-
/**
|
|
46
|
-
* ARTIFACT phase: S3 locations of synthesized infrastructure documents (e.g. CloudFormation templates) evaluated by policy (OPA/rego) checks.
|
|
47
|
-
*
|
|
48
|
-
* @minItems 1
|
|
49
|
-
*/
|
|
50
|
-
infraRefs?: S3Ref1[];
|
|
51
|
-
/**
|
|
52
|
-
* Optional build-source provenance for ARTIFACT calls where the top-level repo/commit describe the source of the build rather than the artifact itself; stamped into verdict provenance verbatim.
|
|
53
|
-
*/
|
|
54
|
-
provenance?: {
|
|
55
|
-
/**
|
|
56
|
-
* GitHub owner/name of the build-source repository.
|
|
57
|
-
*/
|
|
58
|
-
repo: string;
|
|
59
|
-
/**
|
|
60
|
-
* Full 40-hex lowercase commit SHA the artifact was built from.
|
|
61
|
-
*/
|
|
62
|
-
commit: string;
|
|
63
|
-
/**
|
|
64
|
-
* Branch the artifact was built from, caller-supplied provenance.
|
|
65
|
-
*/
|
|
66
|
-
branch?: string;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* ARTIFACT phase: S3 location of the built deployable bundle to scan.
|
|
71
|
-
*/
|
|
72
|
-
export interface S3Ref {
|
|
73
|
-
/**
|
|
74
|
-
* S3 bucket name.
|
|
75
|
-
*/
|
|
76
|
-
bucket: string;
|
|
77
|
-
/**
|
|
78
|
-
* S3 object key.
|
|
79
|
-
*/
|
|
80
|
-
key: string;
|
|
81
|
-
}
|
|
82
|
-
export interface S3Ref1 {
|
|
83
|
-
/**
|
|
84
|
-
* S3 bucket name.
|
|
85
|
-
*/
|
|
86
|
-
bucket: string;
|
|
87
|
-
/**
|
|
88
|
-
* S3 object key.
|
|
89
|
-
*/
|
|
90
|
-
key: string;
|
|
91
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://schemas.harbour.dev/security-scan-input.schema.json",
|
|
4
|
-
"title": "SecurityScanInput",
|
|
5
|
-
"description": "Input to the Isomorph Security Assurance machine (Security Assurance LLD §2). SOURCE (M1) scans an ingested commit; ARTIFACT (M2) scans built outputs — a container image digest, a deployable bundle, and/or synthesized infrastructure — named directly by the caller. `commit` is the identity being scanned; `org/app/env` locate the snapshot (the control-state table has no commit GSI, so a bare commit is not resolvable); `branch` is caller-supplied provenance. When phase is ARTIFACT at least one of `imageDigest`, `bundleRef`, or `infraRefs` must be present.",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"additionalProperties": false,
|
|
8
|
-
"required": ["phase", "org", "app", "env", "repo", "commit", "branch"],
|
|
9
|
-
"if": { "properties": { "phase": { "const": "ARTIFACT" } }, "required": ["phase"] },
|
|
10
|
-
"then": {
|
|
11
|
-
"anyOf": [
|
|
12
|
-
{ "required": ["imageDigest"] },
|
|
13
|
-
{ "required": ["bundleRef"] },
|
|
14
|
-
{ "required": ["infraRefs"] }
|
|
15
|
-
]
|
|
16
|
-
},
|
|
17
|
-
"properties": {
|
|
18
|
-
"phase": {
|
|
19
|
-
"type": "string",
|
|
20
|
-
"enum": ["SOURCE", "ARTIFACT"],
|
|
21
|
-
"description": "Scan phase. SOURCE (M1) scans the ingested snapshot for the commit; ARTIFACT (M2) scans built outputs named by imageDigest/bundleRef/infraRefs — at least one of which must be present."
|
|
22
|
-
},
|
|
23
|
-
"org": {
|
|
24
|
-
"type": "string",
|
|
25
|
-
"minLength": 1,
|
|
26
|
-
"description": "Isomorph organization id, e.g. fourier."
|
|
27
|
-
},
|
|
28
|
-
"app": {
|
|
29
|
-
"type": "string",
|
|
30
|
-
"minLength": 1,
|
|
31
|
-
"description": "Isomorph app id within the org, e.g. focuslist."
|
|
32
|
-
},
|
|
33
|
-
"env": {
|
|
34
|
-
"type": "string",
|
|
35
|
-
"enum": ["preview", "prod"],
|
|
36
|
-
"description": "Environment whose ingested snapshots are searched for the commit. M1 deploys preview-only; prod is contract-stable for M3."
|
|
37
|
-
},
|
|
38
|
-
"repo": {
|
|
39
|
-
"type": "string",
|
|
40
|
-
"minLength": 1,
|
|
41
|
-
"pattern": "^[^/\\s]+/[^/\\s]+$",
|
|
42
|
-
"description": "GitHub owner/name of the source repository, e.g. Fourier-Labs-AI/focus-list."
|
|
43
|
-
},
|
|
44
|
-
"commit": {
|
|
45
|
-
"type": "string",
|
|
46
|
-
"pattern": "^[0-9a-f]{40}$",
|
|
47
|
-
"description": "Full 40-hex lowercase commit SHA — the identity being scanned."
|
|
48
|
-
},
|
|
49
|
-
"branch": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"minLength": 1,
|
|
52
|
-
"description": "Branch name, supplied authoritatively by the caller in v1 (provenance only — never used for resolution)."
|
|
53
|
-
},
|
|
54
|
-
"classification": {
|
|
55
|
-
"type": "string",
|
|
56
|
-
"enum": ["GREEN", "YELLOW", "ORANGE", "RED"],
|
|
57
|
-
"description": "Data classification of the app. Optional in v1 (decided 2026-08-27): when ABSENT the machine assumes the STANDARD profile and stamps classificationDefaulted: true in the verdict provenance. An invalid value still fails closed — only absence defaults. No classifier exists until M4; until then callers state it or accept the default."
|
|
58
|
-
},
|
|
59
|
-
"imageDigest": {
|
|
60
|
-
"type": "string",
|
|
61
|
-
"pattern": "^([^@\\s]+@)?sha256:[0-9a-f]{64}$",
|
|
62
|
-
"description": "ARTIFACT phase: container image to scan, as either a digest-qualified ECR reference (<ecr-uri>@sha256:<64-hex>) or a bare sha256:<64-hex> digest. Digest-addressed only — tags are not accepted, so the scanned bytes are the deployed bytes."
|
|
63
|
-
},
|
|
64
|
-
"bundleRef": {
|
|
65
|
-
"$ref": "#/definitions/S3Ref",
|
|
66
|
-
"description": "ARTIFACT phase: S3 location of the built deployable bundle to scan."
|
|
67
|
-
},
|
|
68
|
-
"infraRefs": {
|
|
69
|
-
"type": "array",
|
|
70
|
-
"items": { "$ref": "#/definitions/S3Ref" },
|
|
71
|
-
"minItems": 1,
|
|
72
|
-
"description": "ARTIFACT phase: S3 locations of synthesized infrastructure documents (e.g. CloudFormation templates) evaluated by policy (OPA/rego) checks."
|
|
73
|
-
},
|
|
74
|
-
"provenance": {
|
|
75
|
-
"type": "object",
|
|
76
|
-
"additionalProperties": false,
|
|
77
|
-
"required": ["repo", "commit"],
|
|
78
|
-
"properties": {
|
|
79
|
-
"repo": {
|
|
80
|
-
"type": "string",
|
|
81
|
-
"minLength": 1,
|
|
82
|
-
"pattern": "^[^/\\s]+/[^/\\s]+$",
|
|
83
|
-
"description": "GitHub owner/name of the build-source repository."
|
|
84
|
-
},
|
|
85
|
-
"commit": {
|
|
86
|
-
"type": "string",
|
|
87
|
-
"pattern": "^[0-9a-f]{40}$",
|
|
88
|
-
"description": "Full 40-hex lowercase commit SHA the artifact was built from."
|
|
89
|
-
},
|
|
90
|
-
"branch": {
|
|
91
|
-
"type": "string",
|
|
92
|
-
"minLength": 1,
|
|
93
|
-
"description": "Branch the artifact was built from, caller-supplied provenance."
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
"description": "Optional build-source provenance for ARTIFACT calls where the top-level repo/commit describe the source of the build rather than the artifact itself; stamped into verdict provenance verbatim."
|
|
97
|
-
}
|
|
98
|
-
},
|
|
99
|
-
"definitions": {
|
|
100
|
-
"S3Ref": {
|
|
101
|
-
"type": "object",
|
|
102
|
-
"additionalProperties": false,
|
|
103
|
-
"required": ["bucket", "key"],
|
|
104
|
-
"properties": {
|
|
105
|
-
"bucket": { "type": "string", "minLength": 1, "description": "S3 bucket name." },
|
|
106
|
-
"key": { "type": "string", "minLength": 1, "description": "S3 object key." }
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
File without changes
|