mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-08 18:37:46 +08:00
fix(provider): harden Agent Identity OAuth lifecycle
This commit is contained in:
@@ -5,9 +5,10 @@ pub use snapshot::ProviderCatalogSnapshot;
|
||||
pub use types::{
|
||||
ProviderCatalogKeyAdaptiveState, ProviderCatalogKeyAdaptiveStateUpdate,
|
||||
ProviderCatalogKeyHealthStateUpdate, ProviderCatalogKeyListOrder, ProviderCatalogKeyListQuery,
|
||||
ProviderCatalogKeyRuntimeMetadataUpdate, ProviderCatalogKeyStatusSnapshotUpdate,
|
||||
ProviderCatalogReadRepository, ProviderCatalogUpstreamMetadataNamespaceUpdate,
|
||||
ProviderCatalogWriteRepository, StoredProviderCatalogEndpoint, StoredProviderCatalogKey,
|
||||
ProviderCatalogKeyOAuthRuntimeStateCasUpdate, ProviderCatalogKeyRuntimeMetadataUpdate,
|
||||
ProviderCatalogKeyStatusSnapshotUpdate, ProviderCatalogReadRepository,
|
||||
ProviderCatalogUpstreamMetadataNamespaceUpdate, ProviderCatalogWriteRepository,
|
||||
StoredProviderCatalogEndpoint, StoredProviderCatalogKey,
|
||||
StoredProviderCatalogKeyMaintenanceSummary, StoredProviderCatalogKeyPage,
|
||||
StoredProviderCatalogKeyStats, StoredProviderCatalogProvider,
|
||||
};
|
||||
|
||||
@@ -31,6 +31,9 @@ impl ProviderCatalogKeyAdaptiveState {
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ProviderCatalogKeyAdaptiveStateUpdate {
|
||||
pub key_id: String,
|
||||
/// Optional auth_config fence for request-owned adaptive feedback.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub expected_encrypted_auth_config: Option<String>,
|
||||
pub expected: ProviderCatalogKeyAdaptiveState,
|
||||
pub next: ProviderCatalogKeyAdaptiveState,
|
||||
/// Top-level status fields owned by adaptive rate-limit learning.
|
||||
@@ -64,9 +67,37 @@ pub struct ProviderCatalogKeyStatusSnapshotUpdate {
|
||||
pub updated_at_unix_secs: Option<u64>,
|
||||
}
|
||||
|
||||
/// Agent/runtime-owned OAuth state update fenced by the exact encrypted
|
||||
/// auth_config observed before the refresh started. Repositories must update
|
||||
/// only these fields and return `false` when the expected config changed.
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ProviderCatalogKeyOAuthRuntimeStateCasUpdate {
|
||||
pub key_id: String,
|
||||
pub expected_encrypted_auth_config: Option<String>,
|
||||
pub encrypted_auth_config: String,
|
||||
/// Optional access-token ciphertext replacement owned by refresh success.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub encrypted_api_key_update: Option<String>,
|
||||
/// `None` preserves expiry; `Some(None)` clears it; `Some(Some(_))` replaces it.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub expires_at_unix_secs_update: Option<Option<u64>>,
|
||||
pub oauth_invalid_at_unix_secs: Option<u64>,
|
||||
pub oauth_invalid_reason: Option<String>,
|
||||
/// Top-level runtime metadata namespaces to merge in the same fenced write.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub upstream_metadata_patch: Option<serde_json::Value>,
|
||||
pub status_snapshot_patch: serde_json::Value,
|
||||
#[serde(default)]
|
||||
pub reset_error_count: bool,
|
||||
pub updated_at_unix_secs: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ProviderCatalogKeyHealthStateUpdate {
|
||||
pub key_id: String,
|
||||
/// Optional auth_config fence for lifecycle-owned health recovery.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
pub expected_encrypted_auth_config: Option<String>,
|
||||
pub expected_health_by_format: Option<serde_json::Value>,
|
||||
pub expected_circuit_breaker_by_format: Option<serde_json::Value>,
|
||||
pub health_by_format: Option<serde_json::Value>,
|
||||
@@ -829,6 +860,18 @@ pub trait ProviderCatalogWriteRepository: Send + Sync {
|
||||
updated_at_unix_secs: Option<u64>,
|
||||
) -> Result<bool, crate::DataLayerError>;
|
||||
|
||||
/// Compare-and-swap OAuth runtime credentials/status without replacing any
|
||||
/// administrator-owned key fields.
|
||||
async fn compare_and_update_key_oauth_runtime_state(
|
||||
&self,
|
||||
_update: &ProviderCatalogKeyOAuthRuntimeStateCasUpdate,
|
||||
) -> Result<bool, crate::DataLayerError> {
|
||||
Err(crate::DataLayerError::InvalidConfiguration(
|
||||
"provider catalog OAuth runtime CAS updates are not supported by this repository"
|
||||
.to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
async fn update_key_health_state(
|
||||
&self,
|
||||
key_id: &str,
|
||||
|
||||
Reference in New Issue
Block a user