feat(credentials): support managed credential synchronization (#2490)

* feat(credentials): support managed credential synchronization

Allow managed callers to upsert credentials with an exact ID, secret,
permissions, reuse policy, and expiry.

Return non-secret attributes plus a public-key fingerprint so callers can
verify relay credential consistency.

Persist imported credentials atomically and preserve identity and expiry
across restarts.

* fix(credentials): make managed upserts durable

Write the candidate credential snapshot before committing it to memory.
Propagate storage failures so controllers can retry instead of observing
false convergence.

Cover a transient storage failure to verify that memory stays unchanged
and the retry persists the credential.

* fix(credentials): atomically replace stored snapshots

Define CredentialStorage::store as an atomic replacement boundary and
use atomic-write-file in the management adapter. This keeps the last
committed credential JSON readable when a replacement fails.

Cover replacement of an existing credential snapshot and keep the
dependency scoped to the management feature.
This commit is contained in:
KKRainbow
2026-08-10 23:20:36 +08:00
committed by GitHub
parent 23d55373a4
commit 0b27ac2885
7 changed files with 313 additions and 7 deletions
+18
View File
@@ -345,6 +345,22 @@ message GenerateCredentialRequest {
message GenerateCredentialResponse {
string credential_id = 1; // UUID
string credential_secret = 2; // private key base64
int64 expiry_unix = 3;
}
message UpsertCredentialRequest {
string credential_id = 1;
string credential_secret = 2;
repeated string groups = 3;
bool allow_relay = 4;
repeated string allowed_proxy_cidrs = 5;
int64 expiry_unix = 6;
optional bool reusable = 7;
InstanceIdentifier instance = 8;
}
message UpsertCredentialResponse {
bool changed = 1;
}
message RevokeCredentialRequest {
@@ -367,6 +383,7 @@ message CredentialInfo {
int64 expiry_unix = 4;
repeated string allowed_proxy_cidrs = 5;
optional bool reusable = 6;
string public_key_fingerprint = 7;
}
message ListCredentialsResponse {
@@ -377,4 +394,5 @@ service CredentialManageRpc {
rpc GenerateCredential(GenerateCredentialRequest) returns (GenerateCredentialResponse);
rpc RevokeCredential(RevokeCredentialRequest) returns (RevokeCredentialResponse);
rpc ListCredentials(ListCredentialsRequest) returns (ListCredentialsResponse);
rpc UpsertCredential(UpsertCredentialRequest) returns (UpsertCredentialResponse);
}