dev.cocore.compute.attestation
Schema Diff
+78 -2
Compatibility Analysis
Breaking Changes Detected
9 breaking changes, 30 non-breaking changes.
Breaking Changes (9)
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.cdHash", sort: "minLength", value: "40" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.cdHash", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.engineLibHash", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.engineLibHash", sort: "minLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.metallibHash", sort: "minLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.metallibHash", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.appAttest.keyId", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.teamId", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.appAttest.object", sort: "maxLength", value: "16384" }
Non-Breaking Changes (30)
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.antiDebug" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.appAttest" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.appAttest.keyId" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.appAttest.object" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.cdHash" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.coreDumpsDisabled" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.engineLibHash" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.envScrubbed" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.getTaskAllow" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.hardenedRuntime" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.inProcessBackend" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.libraryValidation" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.metallibHash" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.teamId" }
- AddedVertex AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.tier" }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.antiDebug", kind: "prop", name: Some("antiDebug") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.appAttest", kind: "prop", name: Some("appAttest") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.cdHash", kind: "prop", name: Some("cdHash") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.coreDumpsDisabled", kind: "prop", name: Some("coreDumpsDisabled") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.engineLibHash", kind: "prop", name: Some("engineLibHash") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.envScrubbed", kind: "prop", name: Some("envScrubbed") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.getTaskAllow", kind: "prop", name: Some("getTaskAllow") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.hardenedRuntime", kind: "prop", name: Some("hardenedRuntime") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.inProcessBackend", kind: "prop", name: Some("inProcessBackend") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.libraryValidation", kind: "prop", name: Some("libraryValidation") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.metallibHash", kind: "prop", name: Some("metallibHash") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.teamId", kind: "prop", name: Some("teamId") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.tier", kind: "prop", name: Some("tier") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body.appAttest", tgt: "dev.cocore.compute.attestation:body.appAttest.keyId", kind: "prop", name: Some("keyId") }
- AddedEdge AddedEdge { src: "dev.cocore.compute.attestation:body.appAttest", tgt: "dev.cocore.compute.attestation:body.appAttest.object", kind: "prop", name: Some("object") }
Migration Guidance
Added Elements
AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.antiDebug" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.appAttest" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.appAttest.keyId" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.appAttest.object" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.cdHash" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.coreDumpsDisabled" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.engineLibHash" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.envScrubbed" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.getTaskAllow" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.hardenedRuntime" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.inProcessBackend" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.libraryValidation" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.metallibHash" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.teamId" }AddedVertex { vertex_id: "dev.cocore.compute.attestation:body.tier" }
Constraint Changes
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.engineLibHash", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.engineLibHash", sort: "minLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.appAttest.object", sort: "maxLength", value: "16384" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.teamId", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.cdHash", sort: "minLength", value: "40" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.cdHash", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.appAttest.keyId", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.metallibHash", sort: "maxLength", value: "64" }
- ConstraintAdded ConstraintAdded { vertex_id: "dev.cocore.compute.attestation:body.metallibHash", sort: "minLength", value: "64" }
Additional Notes
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.antiDebug", kind: "prop", name: Some("antiDebug") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.appAttest", kind: "prop", name: Some("appAttest") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.cdHash", kind: "prop", name: Some("cdHash") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.coreDumpsDisabled", kind: "prop", name: Some("coreDumpsDisabled") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.engineLibHash", kind: "prop", name: Some("engineLibHash") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.envScrubbed", kind: "prop", name: Some("envScrubbed") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.getTaskAllow", kind: "prop", name: Some("getTaskAllow") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.hardenedRuntime", kind: "prop", name: Some("hardenedRuntime") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.inProcessBackend", kind: "prop", name: Some("inProcessBackend") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.libraryValidation", kind: "prop", name: Some("libraryValidation") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.metallibHash", kind: "prop", name: Some("metallibHash") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.teamId", kind: "prop", name: Some("teamId") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body", tgt: "dev.cocore.compute.attestation:body.tier", kind: "prop", name: Some("tier") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body.appAttest", tgt: "dev.cocore.compute.attestation:body.appAttest.keyId", kind: "prop", name: Some("keyId") }
- Non-breaking: AddedEdge { src: "dev.cocore.compute.attestation:body.appAttest", tgt: "dev.cocore.compute.attestation:body.appAttest.object", kind: "prop", name: Some("object") }
1
1
{
2
2
"id": "dev.cocore.compute.attestation",
3
3
"defs": {
4
4
"main": {
5
5
"key": "tid",
6
6
"type": "record",
7
7
"record": {
8
8
"type": "object",
9
9
"required": [
10
10
"publicKey",
11
11
"encryptionPubKey",
12
12
"chipName",
13
13
"hardwareModel",
14
14
"serialNumberHash",
15
15
"osVersion",
16
16
"binaryHash",
17
17
"sipEnabled",
18
18
"secureBootEnabled",
19
19
"secureEnclaveAvailable",
20
20
"authenticatedRootEnabled",
21
21
"selfSignature",
22
22
"attestedAt",
23
23
"expiresAt"
24
24
],
25
25
"properties": {
26
+
"tier": {
27
+
"ref": "dev.cocore.compute.defs#tier",
28
+
"type": "ref",
29
+
"description": "The provider's self-asserted confidentiality tier for work done under this attestation. ADVISORY ONLY: a verifier MUST recompute the tier from the evidence in this record (bound mdaCertChain, cdHash ∈ known-good, posture booleans) and the session handshake, and MUST NOT trust this field. Present so consumers can display the provider's claim before verifying. Optional / additive; absent equivalent to `best-effort`."
30
+
},
31
+
"cdHash": {
32
+
"type": "string",
33
+
"maxLength": 64,
34
+
"minLength": 40,
35
+
"description": "Lowercase hex of the code-signing directory hash (cdhash) the OS actually enforces for the running cocore-provider binary, read from the live process (SecCodeCopySelf / SecCodeCopySigningInformation, fallback csops CS_OPS_CDHASH). This is the measured identity a confidential-tier verifier checks against the known-good set — unlike `binaryHash` it reflects exactly what library validation and `get-task-allow=false` protect. Optional / additive; absent caps the work at `best-effort`."
36
+
},
37
+
"teamId": {
38
+
"type": "string",
39
+
"maxLength": 64,
40
+
"description": "Apple Developer Team Identifier from the code signature of the running binary. A confidential-tier verifier pins this to the expected cocore signing team so a validly-signed but unrelated binary cannot pass. Optional / additive."
41
+
},
26
42
"chipName": {
27
43
"type": "string",
28
44
"maxLength": 64
29
45
},
46
+
"antiDebug": {
47
+
"type": "boolean",
48
+
"description": "True iff the process denied debugger attachment at startup (PT_DENY_ATTACH). Required for `attested-confidential`. Optional / additive; absent treated as false."
49
+
},
50
+
"appAttest": {
51
+
"type": "object",
52
+
"required": [
53
+
"object",
54
+
"keyId"
55
+
],
56
+
"properties": {
57
+
"keyId": {
58
+
"type": "bytes",
59
+
"maxLength": 64,
60
+
"description": "The App Attest key identifier (the SHA-256 of the attested public key) DCAppAttestService.generateKey returned. Verifiers cross-check this equals the credentialId in authData."
61
+
},
62
+
"object": {
63
+
"type": "bytes",
64
+
"maxLength": 16384,
65
+
"description": "The CBOR App Attest attestation object returned by DCAppAttestService.attestKey, as produced for `clientDataHash = sha256(publicKey)`. Contains fmt, attStmt (x5c + receipt), and authData."
66
+
}
67
+
},
68
+
"description": "Optional Apple App Attest evidence — the second, MDM-free path to trustLevel 'hardware-attested'. The provider's signed helper calls DCAppAttestService with `clientDataHash = sha256(publicKey)` (this record's receipt-signing key), so Apple's attestation commits to the signing key by construction. Verifiers MUST, offline: (1) CBOR-decode `object`, requiring fmt 'apple-appattest'; (2) verify the attStmt x5c chain to the embedded Apple App Attest Root CA; (3) recompute `nonce = sha256(authData || sha256(publicKey))` and require it to equal the credential certificate's nonce extension (OID 1.2.840.113635.100.8.2) — THIS is the binding to the signing key; (4) check authData's rpIdHash == sha256(App ID 'TEAMID.dev.cocore.provider'), the AAGUID is the genuine-hardware appattest value, and credentialId == sha256(attested public key) == `keyId`. A bound, valid App Attest object earns 'hardware-attested' exactly as a bound mdaCertChain does. It proves genuine, un-tampered Apple hardware holds a Secure-Enclave key bound to the signing key; it does NOT by itself prove the signing key is SE-resident nor that the running binary is honest (those are carried by the SE-backed signing identity + hardened-runtime + cdHash known-good gate, same self-measurement ceiling as the MDA path)."
69
+
},
30
70
"expiresAt": {
31
71
"type": "string",
32
72
"format": "datetime",
33
73
"description": "Receipts that strong-ref this attestation are only considered fresh if completedAt < expiresAt. Default 24h after attestedAt."
34
74
},
35
75
"osVersion": {
36
76
"type": "string",
37
77
"maxLength": 64
38
78
},
39
79
"publicKey": {
40
80
"type": "string",
41
81
"maxLength": 256,
42
82
"description": "P-256 public key (base64). MUST equal the attestationPubKey of the provider record under the signing DID."
43
83
},
44
84
"attestedAt": {
45
85
"type": "string",
46
86
"format": "datetime"
47
87
},
48
88
"binaryHash": {
49
89
"type": "string",
50
90
"maxLength": 64,
51
91
"minLength": 64,
52
-
"description": "SHA-256 hex of the cocore-provider binary that produced this attestation."
92
+
"description": "SHA-256 hex of the cocore-provider binary that produced this attestation. Back-compat measure of the whole file on disk. For trust decisions `cdHash` supersedes it: the OS enforces the code-signing cdhash, not a whole-file digest, so a verifier deciding `tier` MUST prefer `cdHash` when present and treat `binaryHash` as informational."
53
93
},
54
94
"sipEnabled": {
55
95
"type": "boolean"
56
96
},
97
+
"envScrubbed": {
98
+
"type": "boolean",
99
+
"description": "True iff dynamic-linker injection vectors (DYLD_*) were scrubbed from the environment at startup. Required for `attested-confidential`. Optional / additive; absent treated as false."
100
+
},
101
+
"getTaskAllow": {
102
+
"type": "boolean",
103
+
"description": "Value of the get-task-allow entitlement on the running binary. MUST be false for `attested-confidential` — a true value means another process (even the owner) can attach a debugger and read process memory, defeating confidentiality. Optional / additive; absent treated as true (the unsafe default) so a missing value never silently earns the confidential tier."
104
+
},
57
105
"mdaCertChain": {
58
106
"type": "array",
59
107
"items": {
60
108
"type": "bytes",
61
109
"maxLength": 8192
62
110
},
63
111
"maxLength": 8,
64
-
"description": "Optional Apple Managed Device Attestation certificate chain (DER), leaf first. Present when trustLevel is 'hardware-attested'. Verifiers MUST: (1) verify every adjacent link to the embedded Apple Enterprise Attestation Root CA, enforcing BasicConstraints (non-leaf certs are CAs, the leaf is an end-entity); and (2) require the leaf's P-256 public key to EQUAL this record's `publicKey` — i.e. the chain is BOUND to the receipt-signing key. Without (2) a valid Apple chain for one device could be stapled onto an unrelated signing key, so a chain that verifies but isn't bound MUST NOT earn 'hardware-attested'. Producers (the MDA provisioning tool) MUST therefore attest the signing key itself."
112
+
"description": "Optional Apple Managed Device Attestation certificate chain (DER), leaf first. One of two paths to trustLevel 'hardware-attested' (the other is `appAttest`). Verifiers MUST: (1) verify every adjacent link to the embedded Apple Enterprise Attestation Root CA, enforcing BasicConstraints (non-leaf certs are CAs, the leaf is an end-entity); and (2) BIND the chain to this record's `publicKey` by EITHER the leaf's P-256 public key EQUALLING `publicKey`, OR the Apple freshness extension (OID 1.2.840.113635.100.8.11.1) committing to it as `freshnessCode == sha256(publicKey)`. Without a binding a valid Apple chain for one device could be stapled onto an unrelated signing key, so a chain that verifies but isn't bound MUST NOT earn 'hardware-attested'."
113
+
},
114
+
"metallibHash": {
115
+
"type": "string",
116
+
"maxLength": 64,
117
+
"minLength": 64,
118
+
"description": "SHA-256 hex of the precompiled Metal shader library (`mlx.metallib` or equivalent) the in-process inference engine loads at runtime. The GPU kernels that touch the plaintext live here, so a confidential verifier pins this to a known-good value alongside `cdHash`. Absent when no native engine is loaded (e.g. the subprocess/best-effort backend). Optional / additive."
65
119
},
66
120
"rdmaDisabled": {
67
121
"type": "boolean"
68
122
},
123
+
"engineLibHash": {
124
+
"type": "string",
125
+
"maxLength": 64,
126
+
"minLength": 64,
127
+
"description": "SHA-256 hex of the dynamic library that runs the in-process inference engine (e.g. `libCoCoreMLX.dylib`). When the engine is a separately-loaded dylib rather than code statically inside the agent binary, the `cdHash` does not cover it, so a confidential verifier pins this too. Enforced library validation already blocks a different team's dylib; this additionally locks the hash within the provider team's own blessed releases. Absent when inference runs in a subprocess or fully inside the measured binary. Optional / additive."
128
+
},
69
129
"hardwareModel": {
70
130
"type": "string",
71
131
"maxLength": 64,
72
132
"description": "DMI string, e.g. 'Mac15,8'."
73
133
},
74
134
"selfSignature": {
75
135
"type": "bytes",
76
136
"maxLength": 256,
77
137
"description": "Secure Enclave P-256 signature (DER) over a sorted-key canonical JSON of every other field in this record. Verifiers MUST reconstruct the canonical JSON byte-for-byte before checking."
78
138
},
139
+
"hardenedRuntime": {
140
+
"type": "boolean",
141
+
"description": "True iff the running binary is signed with the hardened runtime (CS_RUNTIME). Required for `attested-confidential`. Optional / additive; absent treated as false."
142
+
},
79
143
"encryptionPubKey": {
80
144
"type": "string",
81
145
"maxLength": 128,
82
146
"description": "X25519 public key (base64) bound to the same Secure Enclave identity. Proves a single device controls both signing and request-encryption keys."
83
147
},
148
+
"inProcessBackend": {
149
+
"type": "boolean",
150
+
"description": "True iff inference runs INSIDE this measured, signed binary (native in-process engine) rather than in an owner-controlled subprocess/interpreter. This is THE load-bearing confidentiality property — if false, the prompt is handed to a process the attestation does not cover, so the work can never be `attested-confidential`. Optional / additive; absent treated as false."
151
+
},
84
152
"serialNumberHash": {
85
153
"type": "string",
86
154
"maxLength": 64,
87
155
"minLength": 64,
88
156
"description": "SHA-256 hex of (serialNumber || providerDID). Hashed so the public record never leaks raw serials. When an mdaCertChain is present, the serialNumber MUST be the one the verified MDA leaf attests (not a self-reported value), so the hashed device identity is anchored to the chain."
89
157
},
158
+
"coreDumpsDisabled": {
159
+
"type": "boolean",
160
+
"description": "True iff core dumps were disabled at startup (RLIMIT_CORE=0), so a crash cannot spill plaintext to disk. Required for `attested-confidential`. Optional / additive; absent treated as false."
161
+
},
162
+
"libraryValidation": {
163
+
"type": "boolean",
164
+
"description": "True iff library validation is enforced (the binary will not load libraries signed by a different team / unsigned code). Closes the dylib-injection path. Required for `attested-confidential`. Optional / additive; absent treated as false."
165
+
},
90
166
"secureBootEnabled": {
91
167
"type": "boolean"
92
168
},
93
169
"secureEnclaveAvailable": {
94
170
"type": "boolean"
95
171
},
96
172
"authenticatedRootEnabled": {
97
173
"type": "boolean"
98
174
}
99
175
}
100
176
}
101
177
}
102
178
},
103
179
"$type": "com.atproto.lexicon.schema",
104
180
"lexicon": 1,
105
181
"description": "A snapshot of a provider machine's hardware and software state, signed by its Secure Enclave. Content-addressed: many receipts strong-ref the same attestation record until the underlying state changes (binary upgrade, OS update, key rotation)."
106
182
}