mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-29 08:27:06 +00:00
3b5164032a
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.
220 lines
9.5 KiB
JSON
220 lines
9.5 KiB
JSON
{
|
|
"protocolVersion": "v1",
|
|
"fixtureSet": "inventory",
|
|
"fixture": "secret-like-vectors",
|
|
"description": "An agent, a proxy, or an attacker attaches credential-shaped and customer-identifying members to an otherwise valid snapshot. Every one is an unknown optional member, so the frozen rule applies unchanged: accepted, discarded, never persisted, never echoed back, and never logged in raw form. Rejecting them instead would break additive compatibility and would put the secret text into an error message, so discarding is the safer and the frozen behaviour. Each vector carries the same content hash as the valid fixture's fully populated snapshot, which proves nothing here reaches storage. The literal values below are non-functional examples, not real credentials.",
|
|
"baseVector": "fully populated snapshot",
|
|
"baseContentHash": "e1cba9f30a26b94bb289a8a4b630a704dafaeb4960bffd38cef98e3d2581518f",
|
|
"errorMessagesNameUnknownMembers": false,
|
|
"vectors": [
|
|
{
|
|
"name": "S3 access key and secret key attached to the snapshot",
|
|
"category": "secret-like",
|
|
"sameContentHashAs": "fully populated snapshot",
|
|
"secretLikeMembers": ["accessKeyId", "secretAccessKey", "sessionToken"],
|
|
"input": {
|
|
"protocolVersion": "v1",
|
|
"rustfsVersion": "1.4.2",
|
|
"osVersion": { "family": "linux", "major": 6, "minor": 8 },
|
|
"nodeCount": 8,
|
|
"driveCount": 96,
|
|
"capacityTotalBytes": 1099511627776,
|
|
"capacityUsedBytes": 412316860416,
|
|
"coarseFlags": ["cluster.degraded", "drive.offline"],
|
|
"accessKeyId": "AKIAIOSFODNN7EXAMPLE",
|
|
"secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
|
"sessionToken": "FwoGZXIvYXdzEExampleSessionTokenValue"
|
|
},
|
|
"expected": {
|
|
"decision": "ACCEPT",
|
|
"reason": null,
|
|
"httpStatus": null,
|
|
"retained": [
|
|
"protocolVersion",
|
|
"rustfsVersion",
|
|
"osVersion",
|
|
"nodeCount",
|
|
"driveCount",
|
|
"capacityTotalBytes",
|
|
"capacityUsedBytes",
|
|
"coarseFlags"
|
|
],
|
|
"discarded": ["accessKeyId", "secretAccessKey", "sessionToken"],
|
|
"defaultsApplied": {},
|
|
"canonicalJson": "{\"capacityTotalBytes\":1099511627776,\"capacityUsedBytes\":412316860416,\"coarseFlags\":[\"cluster.degraded\",\"drive.offline\"],\"driveCount\":96,\"nodeCount\":8,\"osVersion\":{\"family\":\"linux\",\"major\":6,\"minor\":8},\"rustfsVersion\":\"1.4.2\"}",
|
|
"contentHash": "e1cba9f30a26b94bb289a8a4b630a704dafaeb4960bffd38cef98e3d2581518f",
|
|
"echoedBack": [],
|
|
"stored": [],
|
|
"logged": []
|
|
}
|
|
},
|
|
{
|
|
"name": "bearer token and private key material attached to the snapshot",
|
|
"category": "secret-like",
|
|
"sameContentHashAs": "fully populated snapshot",
|
|
"secretLikeMembers": ["authorization", "devicePrivateKeyPem", "kmsMasterKey"],
|
|
"input": {
|
|
"protocolVersion": "v1",
|
|
"rustfsVersion": "1.4.2",
|
|
"osVersion": { "family": "linux", "major": 6, "minor": 8 },
|
|
"nodeCount": 8,
|
|
"driveCount": 96,
|
|
"capacityTotalBytes": 1099511627776,
|
|
"capacityUsedBytes": 412316860416,
|
|
"coarseFlags": ["cluster.degraded", "drive.offline"],
|
|
"authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.e30.c2lnbmF0dXJl",
|
|
"devicePrivateKeyPem": "-----BEGIN PRIVATE KEY-----\nMEECAQAwEwYHKoZIzj0CAQYIKoZIzj0DAQcEJzAlAgEBBCBleGFtcGxl\n-----END PRIVATE KEY-----",
|
|
"kmsMasterKey": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
},
|
|
"expected": {
|
|
"decision": "ACCEPT",
|
|
"reason": null,
|
|
"httpStatus": null,
|
|
"retained": [
|
|
"protocolVersion",
|
|
"rustfsVersion",
|
|
"osVersion",
|
|
"nodeCount",
|
|
"driveCount",
|
|
"capacityTotalBytes",
|
|
"capacityUsedBytes",
|
|
"coarseFlags"
|
|
],
|
|
"discarded": ["authorization", "devicePrivateKeyPem", "kmsMasterKey"],
|
|
"defaultsApplied": {},
|
|
"canonicalJson": "{\"capacityTotalBytes\":1099511627776,\"capacityUsedBytes\":412316860416,\"coarseFlags\":[\"cluster.degraded\",\"drive.offline\"],\"driveCount\":96,\"nodeCount\":8,\"osVersion\":{\"family\":\"linux\",\"major\":6,\"minor\":8},\"rustfsVersion\":\"1.4.2\"}",
|
|
"contentHash": "e1cba9f30a26b94bb289a8a4b630a704dafaeb4960bffd38cef98e3d2581518f",
|
|
"echoedBack": [],
|
|
"stored": [],
|
|
"logged": []
|
|
}
|
|
},
|
|
{
|
|
"name": "bucket object path and endpoint members attached to the snapshot",
|
|
"category": "secret-like",
|
|
"sameContentHashAs": "fully populated snapshot",
|
|
"secretLikeMembers": ["buckets", "largestObjectKey", "dataPaths", "endpoint"],
|
|
"input": {
|
|
"protocolVersion": "v1",
|
|
"rustfsVersion": "1.4.2",
|
|
"osVersion": { "family": "linux", "major": 6, "minor": 8 },
|
|
"nodeCount": 8,
|
|
"driveCount": 96,
|
|
"capacityTotalBytes": 1099511627776,
|
|
"capacityUsedBytes": 412316860416,
|
|
"coarseFlags": ["cluster.degraded", "drive.offline"],
|
|
"buckets": ["customer-backups", "prod-media-eu"],
|
|
"largestObjectKey": "invoices/2026/08/inv-1.pdf",
|
|
"dataPaths": ["/var/lib/rustfs/data/disk1", "C:\\rustfs\\data"],
|
|
"endpoint": "https://rustfs.internal:9000"
|
|
},
|
|
"expected": {
|
|
"decision": "ACCEPT",
|
|
"reason": null,
|
|
"httpStatus": null,
|
|
"retained": [
|
|
"protocolVersion",
|
|
"rustfsVersion",
|
|
"osVersion",
|
|
"nodeCount",
|
|
"driveCount",
|
|
"capacityTotalBytes",
|
|
"capacityUsedBytes",
|
|
"coarseFlags"
|
|
],
|
|
"discarded": ["buckets", "dataPaths", "endpoint", "largestObjectKey"],
|
|
"defaultsApplied": {},
|
|
"canonicalJson": "{\"capacityTotalBytes\":1099511627776,\"capacityUsedBytes\":412316860416,\"coarseFlags\":[\"cluster.degraded\",\"drive.offline\"],\"driveCount\":96,\"nodeCount\":8,\"osVersion\":{\"family\":\"linux\",\"major\":6,\"minor\":8},\"rustfsVersion\":\"1.4.2\"}",
|
|
"contentHash": "e1cba9f30a26b94bb289a8a4b630a704dafaeb4960bffd38cef98e3d2581518f",
|
|
"echoedBack": [],
|
|
"stored": [],
|
|
"logged": []
|
|
}
|
|
},
|
|
{
|
|
"name": "redacted configuration and customer identifiers attached to the snapshot",
|
|
"category": "secret-like",
|
|
"sameContentHashAs": "fully populated snapshot",
|
|
"secretLikeMembers": ["configuration", "customerName", "nodeHostnames"],
|
|
"input": {
|
|
"protocolVersion": "v1",
|
|
"rustfsVersion": "1.4.2",
|
|
"osVersion": { "family": "linux", "major": 6, "minor": 8 },
|
|
"nodeCount": 8,
|
|
"driveCount": 96,
|
|
"capacityTotalBytes": 1099511627776,
|
|
"capacityUsedBytes": 412316860416,
|
|
"coarseFlags": ["cluster.degraded", "drive.offline"],
|
|
"configuration": { "tls": { "minVersion": "1.3" }, "erasure": "RUSTFS_ERASURE_SET_SIZE=12" },
|
|
"customerName": "acme-corp",
|
|
"nodeHostnames": ["node-3.storage.example.com", "10.4.2.17"]
|
|
},
|
|
"expected": {
|
|
"decision": "ACCEPT",
|
|
"reason": null,
|
|
"httpStatus": null,
|
|
"retained": [
|
|
"protocolVersion",
|
|
"rustfsVersion",
|
|
"osVersion",
|
|
"nodeCount",
|
|
"driveCount",
|
|
"capacityTotalBytes",
|
|
"capacityUsedBytes",
|
|
"coarseFlags"
|
|
],
|
|
"discarded": ["configuration", "customerName", "nodeHostnames"],
|
|
"defaultsApplied": {},
|
|
"canonicalJson": "{\"capacityTotalBytes\":1099511627776,\"capacityUsedBytes\":412316860416,\"coarseFlags\":[\"cluster.degraded\",\"drive.offline\"],\"driveCount\":96,\"nodeCount\":8,\"osVersion\":{\"family\":\"linux\",\"major\":6,\"minor\":8},\"rustfsVersion\":\"1.4.2\"}",
|
|
"contentHash": "e1cba9f30a26b94bb289a8a4b630a704dafaeb4960bffd38cef98e3d2581518f",
|
|
"echoedBack": [],
|
|
"stored": [],
|
|
"logged": []
|
|
}
|
|
},
|
|
{
|
|
"name": "secret material hidden inside osVersion and inside a coarse flag token",
|
|
"category": "secret-like",
|
|
"sameContentHashAs": "fully populated snapshot",
|
|
"secretLikeMembers": ["osVersion.licenseKey", "coarseFlags[akiaiosfodnn7example]"],
|
|
"input": {
|
|
"protocolVersion": "v1",
|
|
"rustfsVersion": "1.4.2",
|
|
"osVersion": {
|
|
"family": "linux",
|
|
"major": 6,
|
|
"minor": 8,
|
|
"licenseKey": "RUSTFS-PROD-4821-9930-ACME"
|
|
},
|
|
"nodeCount": 8,
|
|
"driveCount": 96,
|
|
"capacityTotalBytes": 1099511627776,
|
|
"capacityUsedBytes": 412316860416,
|
|
"coarseFlags": ["cluster.degraded", "drive.offline", "akiaiosfodnn7example"]
|
|
},
|
|
"expected": {
|
|
"decision": "ACCEPT",
|
|
"reason": null,
|
|
"httpStatus": null,
|
|
"retained": [
|
|
"protocolVersion",
|
|
"rustfsVersion",
|
|
"osVersion",
|
|
"nodeCount",
|
|
"driveCount",
|
|
"capacityTotalBytes",
|
|
"capacityUsedBytes",
|
|
"coarseFlags"
|
|
],
|
|
"discarded": ["coarseFlags[akiaiosfodnn7example]", "osVersion.licenseKey"],
|
|
"defaultsApplied": {},
|
|
"canonicalJson": "{\"capacityTotalBytes\":1099511627776,\"capacityUsedBytes\":412316860416,\"coarseFlags\":[\"cluster.degraded\",\"drive.offline\"],\"driveCount\":96,\"nodeCount\":8,\"osVersion\":{\"family\":\"linux\",\"major\":6,\"minor\":8},\"rustfsVersion\":\"1.4.2\"}",
|
|
"contentHash": "e1cba9f30a26b94bb289a8a4b630a704dafaeb4960bffd38cef98e3d2581518f",
|
|
"echoedBack": [],
|
|
"stored": [],
|
|
"logged": []
|
|
}
|
|
}
|
|
]
|
|
}
|