Files
rustfs/protocol/agent/v1/fixtures/version/additive-compatibility.json
T
overtrue 3b5164032a feat(connect): add device identity store and registration proof
A RustFS cluster device needs a durable identity before it can exchange a
one-time registration token for a certificate. This adds the device-side
half of that exchange, which rustfs/connect already verifies.

`connect::identity` builds the canonical registration transcript frozen by
protocol/agent/v1/registration-proof.md, signs it as low-S ES256, and emits
the PKCS#10 certificate request Connect consumes for its SubjectPublicKeyInfo.
`connect::identity_store` seals the P-256 key at mode 0600 and publishes it
through a no-clobber link, so a retry or a concurrent start returns the
original identity rather than minting a second one, and a corrupt or widened
key is refused rather than silently replaced.

The protocol fixture set is copied here byte-identically because
fixture-sets.json names this repository as the consumer copy; the tests
verify it against its own manifests and cross-verify Connect-produced ECDSA
proofs against transcripts rebuilt locally.

Nothing starts a task or touches the S3 data path: an unenrolled deployment
generates no key and holds no identity.
2026-08-19 12:54:50 +08:00

105 lines
2.9 KiB
JSON

{
"protocolVersion": "v1",
"fixtureSet": "version",
"fixture": "additive-compatibility",
"description": "Release skew in both directions. v1 grows by optional fields only, so an unknown field is discarded and an absent one takes its documented default.",
"vectors": [
{
"name": "new agent sends a v1 field this Connect does not know",
"direction": "new-agent-to-old-connect",
"payload": {
"protocolVersion": "v1",
"agentVersion": "1.9.0",
"capabilities": ["heartbeat"],
"telemetryProfile": "extended"
},
"expected": {
"decision": "ACCEPT",
"retained": ["protocolVersion", "agentVersion", "capabilities"],
"discarded": ["telemetryProfile"],
"defaultsApplied": {},
"echoedBack": [],
"stored": []
}
},
{
"name": "new agent sends several unknown optional fields at once",
"direction": "new-agent-to-old-connect",
"payload": {
"protocolVersion": "v1",
"capabilities": ["heartbeat", "inventory", "bundle.upload"],
"telemetryProfile": "extended",
"regionHint": "eu-west",
"experimentalFlags": {
"fastHeartbeat": true
}
},
"expected": {
"decision": "ACCEPT",
"retained": ["protocolVersion", "capabilities"],
"discarded": ["telemetryProfile", "regionHint", "experimentalFlags"],
"defaultsApplied": {
"agentVersion": null
},
"echoedBack": [],
"stored": []
}
},
{
"name": "old agent omits every optional field",
"direction": "old-agent-to-new-connect",
"payload": {
"protocolVersion": "v1"
},
"expected": {
"decision": "ACCEPT",
"retained": ["protocolVersion"],
"discarded": [],
"defaultsApplied": {
"agentVersion": null,
"capabilities": []
},
"echoedBack": [],
"stored": []
}
},
{
"name": "old agent reports no capabilities but names itself",
"direction": "old-agent-to-new-connect",
"payload": {
"protocolVersion": "v1",
"agentVersion": "1.0.0"
},
"expected": {
"decision": "ACCEPT",
"retained": ["protocolVersion", "agentVersion"],
"discarded": [],
"defaultsApplied": {
"capabilities": []
},
"echoedBack": [],
"stored": []
}
},
{
"name": "unknown fields do not rescue an unsupported major version",
"direction": "new-agent-to-old-connect",
"payload": {
"protocolVersion": "v2",
"agentVersion": "2.0.0",
"compatibilityShim": "v1"
},
"expected": {
"decision": "REJECT",
"reason": "UNSUPPORTED_PROTOCOL",
"httpStatus": 400,
"retained": [],
"discarded": [],
"defaultsApplied": {},
"echoedBack": [],
"stored": []
}
}
]
}