Files
rustfs/protocol/agent/v1/fixtures/redaction/secret-vectors.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

343 lines
12 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"protocolVersion": "v1",
"fixtureSet": "redaction",
"fixture": "secret-vectors",
"description": "Realistic secret material presented to the engine. Every literal in secretLiterals must be absent from the redacted output, from any log, and from any exception. The example values are synthetic: the PEM body is not a usable key and the AWS values are the documented example credentials.",
"expectations": [
"expectedCanonicalJson is the exact output bytes for this document at rustfs.connect.redaction.v1.",
"valueRule names the rule that fires for ruleSubject; a null valueRule means the removal comes from the allow-list, a key rule, or the ASCII key rule instead."
],
"vectors": [
{
"name": "an S3 access key id smuggled into the version field",
"source": "inventory",
"valueRule": "AWS_ACCESS_KEY_ID",
"ruleSubject": "AKIAIOSFODNN7EXAMPLE",
"document": {
"rustfsVersion": "AKIAIOSFODNN7EXAMPLE",
"nodeCount": 4
},
"secretLiterals": [
"AKIAIOSFODNN7EXAMPLE"
],
"expectedCanonicalJson": "{\"nodeCount\":4,\"rustfsVersion\":\"[REDACTED]\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "an S3 secret access key standing alone in an offline OS summary",
"source": "offline-diagnostic",
"valueRule": "AWS_SECRET_ACCESS_KEY",
"ruleSubject": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"document": {
"osSummary": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"rustfsVersion": "1.19.4"
},
"secretLiterals": [
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
],
"expectedCanonicalJson": "{\"osSummary\":\"[REDACTED]\",\"rustfsVersion\":\"1.19.4\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a captured bearer authorization header in a kernel summary",
"source": "offline-diagnostic",
"valueRule": "BEARER_TOKEN",
"ruleSubject": "Linux 6.8.0; upstream call used Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"document": {
"kernelSummary": "Linux 6.8.0; upstream call used Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk"
},
"secretLiterals": [
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk"
],
"expectedCanonicalJson": "{\"kernelSummary\":\"[REDACTED]\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a JSON web token inside a heartbeat capability list",
"source": "heartbeat",
"valueRule": "JWT",
"ruleSubject": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"document": {
"capabilities": [
"inventory",
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk",
"jobs"
],
"sequence": 12
},
"secretLiterals": [
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJydXN0ZnMtZGV2aWNlIn0.dBjftJeZ4CVPmB92K27uhbUJU1p1r_wW1gFWFOEjXk"
],
"expectedCanonicalJson": "{\"capabilities\":[\"inventory\",\"[REDACTED]\",\"jobs\"],\"sequence\":12}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a connection string carrying an embedded password",
"source": "offline-diagnostic",
"valueRule": "URL_CREDENTIALS",
"ruleSubject": "postgresql://rustfs:s3cr3t-p4ss@db.internal:5432/connect",
"document": {
"filesystemSummary": "postgresql://rustfs:s3cr3t-p4ss@db.internal:5432/connect"
},
"secretLiterals": [
"s3cr3t-p4ss",
"db.internal"
],
"expectedCanonicalJson": "{\"filesystemSummary\":\"[REDACTED]\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a PEM private key nested inside a coarse node summary",
"source": "heartbeat",
"valueRule": "PEM_PRIVATE_KEY",
"ruleSubject": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxEXAMPLEKEYBODYnotarealkey0000000000000000000000\nEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE=\n-----END RSA PRIVATE KEY-----",
"document": {
"coarseNodeSummary": {
"healthy": 4,
"note": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxEXAMPLEKEYBODYnotarealkey0000000000000000000000\nEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE=\n-----END RSA PRIVATE KEY-----"
}
},
"secretLiterals": [
"-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxEXAMPLEKEYBODYnotarealkey0000000000000000000000\nEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLE=\n-----END RSA PRIVATE KEY-----",
"EXAMPLEKEYBODY"
],
"expectedCanonicalJson": "{\"coarseNodeSummary\":{\"healthy\":4,\"note\":\"[REDACTED]\"}}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a DSN password assignment in a CPU summary",
"source": "offline-diagnostic",
"valueRule": "PASSWORD_ASSIGNMENT",
"ruleSubject": "Server=db;User Id=rustfs;Password=hunter2xyz;",
"document": {
"cpuSummary": "Server=db;User Id=rustfs;Password=hunter2xyz;"
},
"secretLiterals": [
"hunter2xyz"
],
"expectedCanonicalJson": "{\"cpuSummary\":\"[REDACTED]\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a session identifier assignment appended to an OS version",
"source": "inventory",
"valueRule": "SESSION_ID_ASSIGNMENT",
"ruleSubject": "Ubuntu 22.04.5 LTS; PHPSESSID=9f8a7b6c5d4e3f2a1b0c",
"document": {
"osVersion": "Ubuntu 22.04.5 LTS; PHPSESSID=9f8a7b6c5d4e3f2a1b0c"
},
"secretLiterals": [
"9f8a7b6c5d4e3f2a1b0c"
],
"expectedCanonicalJson": "{\"osVersion\":\"[REDACTED]\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a registration token assignment in an agent version string",
"source": "heartbeat",
"valueRule": "CREDENTIAL_ASSIGNMENT",
"ruleSubject": "rustfs-agent/1.19.4 registration_token=rft-9f8a7b6c5d4e3f2a1b0c",
"document": {
"agentVersion": "rustfs-agent/1.19.4 registration_token=rft-9f8a7b6c5d4e3f2a1b0c"
},
"secretLiterals": [
"rft-9f8a7b6c5d4e3f2a1b0c"
],
"expectedCanonicalJson": "{\"agentVersion\":\"[REDACTED]\"}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "KMS key material recognised by its key name alone",
"source": "inventory",
"valueRule": null,
"ruleSubject": null,
"document": {
"coarseFlags": {
"degraded": false,
"kms_master_key": "AQIDAHhEXAMPLEkmsDataKeyCiphertext"
}
},
"secretLiterals": [
"AQIDAHhEXAMPLEkmsDataKeyCiphertext"
],
"expectedCanonicalJson": "{\"coarseFlags\":{\"degraded\":false,\"kms_master_key\":\"[REDACTED]\"}}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a secret access key under a separated and mixed-case key name",
"source": "inventory",
"valueRule": null,
"ruleSubject": null,
"document": {
"coarseFlags": {
"Secret-Access-Key": "zz9EXAMPLEkey",
"driveCount": 24
}
},
"secretLiterals": [
"zz9EXAMPLEkey"
],
"expectedCanonicalJson": "{\"coarseFlags\":{\"Secret-Access-Key\":\"[REDACTED]\",\"driveCount\":24}}",
"expectedCounts": {
"droppedField": 0,
"redactedValue": 1,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "a brand new secret-bearing field that matches no value rule at all",
"source": "inventory",
"valueRule": null,
"ruleSubject": null,
"document": {
"rustfsVersion": "1.19.4",
"vendorSupportCredential": "ordinary-looking-handle-42",
"objectStoreRootPassphrase": "correct horse battery staple"
},
"secretLiterals": [
"ordinary-looking-handle-42",
"correct horse battery staple",
"vendorSupportCredential",
"objectStoreRootPassphrase"
],
"expectedCanonicalJson": "{\"rustfsVersion\":\"1.19.4\"}",
"expectedCounts": {
"droppedField": 2,
"redactedValue": 0,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 2
},
{
"name": "deferred L2 and L3 collection is refused by the allow-list",
"source": "offline-diagnostic",
"valueRule": null,
"ruleSubject": null,
"document": {
"rustfsVersion": "1.19.4",
"configuration": {
"endpoint": "https://s3.example.internal"
},
"logs": [
"level=error msg=\"auth failed for user rustfs\""
],
"traces": "span 8f2c1a",
"profiles": "cpu.pprof"
},
"secretLiterals": [
"s3.example.internal",
"auth failed for user rustfs",
"span 8f2c1a",
"cpu.pprof"
],
"expectedCanonicalJson": "{\"rustfsVersion\":\"1.19.4\"}",
"expectedCounts": {
"droppedField": 4,
"redactedValue": 0,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 4
},
{
"name": "a confusable non-ASCII key inside an allow-listed object is dropped",
"source": "inventory",
"valueRule": null,
"ruleSubject": null,
"document": {
"coarseFlags": {
"ecretAccessKey": "AKIAIOSFODNN7EXAMPLE",
"degraded": true
}
},
"secretLiterals": [
"AKIAIOSFODNN7EXAMPLE",
"ecretAccessKey"
],
"expectedCanonicalJson": "{\"coarseFlags\":{\"degraded\":true}}",
"expectedCounts": {
"droppedField": 1,
"redactedValue": 0,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 1
},
{
"name": "an allow-listed object that loses every entry is removed entirely",
"source": "heartbeat",
"valueRule": null,
"ruleSubject": null,
"document": {
"coarseNodeSummary": {
"perNode": {
"ostname": "node-01.rustfs.internal"
}
},
"sequence": 7
},
"secretLiterals": [
"node-01.rustfs.internal",
"perNode",
"coarseNodeSummary"
],
"expectedCanonicalJson": "{\"sequence\":7}",
"expectedCounts": {
"droppedField": 3,
"redactedValue": 0,
"redactedOversizeValue": 0
},
"expectedRedactedCount": 3
}
]
}