From 1944bc39858194e3d0172b10806ae84f3be9a52d Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Tue, 18 Aug 2026 17:31:39 -0700 Subject: [PATCH 1/5] feat(providers): store refresh credentials in credential drivers Signed-off-by: Mrunal Patel --- .agents/skills/openshell-cli/SKILL.md | 8 + architecture/gateway.md | 22 +- crates/openshell-server/src/credentials.rs | 138 ++++ crates/openshell-server/src/grpc/provider.rs | 192 +++++- .../openshell-server/src/provider_refresh.rs | 563 ++++++++++++++-- docs/reference/gateway-config.mdx | 4 +- docs/sandboxes/providers-v2.mdx | 23 +- proto/credential_driver.proto | 12 +- proto/openshell.proto | 13 + sdk/go/proto/openshellv1/openshell.pb.go | 628 ++++++++++-------- 10 files changed, 1237 insertions(+), 366 deletions(-) diff --git a/.agents/skills/openshell-cli/SKILL.md b/.agents/skills/openshell-cli/SKILL.md index 1cee3d5c37..fcbc5be783 100644 --- a/.agents/skills/openshell-cli/SKILL.md +++ b/.agents/skills/openshell-cli/SKILL.md @@ -180,6 +180,14 @@ openshell provider refresh rotate my-outlook --credential-key MS_GRAPH_ACCESS_TO Prefer `--secret-material-env KEY[=ENVVAR]` for secret refresh material. `--material KEY=VALUE` is for non-secret material; `--secret-material-key` marks supplied material keys as secret. +The gateway stores secret refresh material through its active credential driver. +With Vault selected, refresh tokens, client secrets, and private keys live in +Vault alongside injectable provider credentials; refresh state contains only +opaque handles. A credential-backend read or write failure makes refresh fail +closed rather than falling back to inline storage. During an upgrade that +migrates legacy inline refresh material, stop all older gateway replicas before +starting the new version; do not use a mixed-version rolling update. + Gateway-managed refresh credentials use an identity-stable workload handle. Routine automatic refresh and `provider refresh rotate` update the access token behind that handle, so long-running processes do not need to restart. Running diff --git a/architecture/gateway.md b/architecture/gateway.md index db8f2508e8..33fd680d75 100644 --- a/architecture/gateway.md +++ b/architecture/gateway.md @@ -317,19 +317,23 @@ default WAL journal mode), which mirror the same sensitive contents. Persisted state includes sandboxes, providers, provider credential refresh state, SSH sessions, policy revisions, settings, inference configuration, and -deployment records. Provider refresh material is stored as a separate object -scoped to the provider instance through `objects.scope`; the provider record -keeps only the current injectable credential values and optional per-credential -expiry timestamps. A refresh normally mints one credential, but a strategy may +deployment records. Provider refresh state is stored as a separate object +scoped to the provider instance through `objects.scope`. Its non-secret +configuration remains inline, while refresh tokens, client secrets, private +keys, and other secret source material are stored through the active credential +driver and represented by opaque handles. The provider record keeps only the +current injectable credential handles and optional per-credential expiry +timestamps. A refresh normally mints one credential, but a strategy may co-mint several (AWS STS mints the access key, secret key, and session token in one call); the refresh state pins the resolved set of env keys it owns so collision checks reserve all of them before the first mint. Provider records keep inline credential values only for legacy records created before credential -driver storage. New provider writes keep driver-owned credential handles. When -no external credential driver is configured, gateways use server-owned encrypted -database credential storage for defense in depth. Multi-replica deployments can -use that default with a shared database and shared key-encryption key, or opt -into an external backend such as Vault or Kubernetes Secrets. +driver storage. New provider and refresh-material writes keep driver-owned +credential handles. When no external credential driver is configured, gateways +use server-owned encrypted database credential storage for defense in depth. +Multi-replica deployments can use that default with a shared database and +shared key-encryption key, or opt into an external backend such as Vault or +Kubernetes Secrets. ### Optimistic Concurrency (CAS) diff --git a/crates/openshell-server/src/credentials.rs b/crates/openshell-server/src/credentials.rs index 71503f3bf4..396be9de22 100644 --- a/crates/openshell-server/src/credentials.rs +++ b/crates/openshell-server/src/credentials.rs @@ -38,6 +38,7 @@ use openshell_driver_db_credstore::{ }; use openshell_driver_kubernetes_secrets::KubernetesSecretsCredentialDriver; use openshell_driver_vault::VaultCredentialDriver; +use sha2::{Digest, Sha256}; #[cfg(unix)] use tokio::net::UnixStream; #[cfg(unix)] @@ -53,6 +54,8 @@ use crate::persistence::{PersistenceError, Store, WriteCondition}; const DEFAULT_CREDENTIAL_DRIVER_STARTUP_TIMEOUT_SECS: u64 = 10; const DEFAULT_CREDENTIAL_DRIVER_RPC_TIMEOUT_SECS: u64 = 30; +const REFRESH_MATERIAL_CREDENTIAL_KEY_DOMAIN: &[u8] = + b"openshell-refresh-material-credential-key-v1"; const COMMON_CREDENTIAL_DRIVER_FIELDS: &[&str] = &[ "transport", "socket_path", @@ -89,6 +92,14 @@ pub struct ResolvedProviderCredentials { pub expires_at_ms: HashMap, } +#[derive(Debug, Clone, Copy)] +pub struct RefreshMaterialScope<'a> { + pub provider_name: &'a str, + pub workspace: &'a str, + pub provider_id: &'a str, + pub credential_key: &'a str, +} + #[derive(Debug, Clone)] pub struct CredentialRuntime { registry: CredentialDriverRegistry, @@ -328,6 +339,123 @@ impl CredentialRuntime { Ok(successes) } + /// Store gateway-only refresh material through the active credential + /// driver. Material names never become backend keys directly; a + /// deterministic driver-safe key binds each slot to its injectable + /// credential without exposing caller-controlled names in backend paths. + pub async fn store_refresh_material_with_object_id( + &self, + scope: RefreshMaterialScope<'_>, + object_id: &str, + material: &HashMap, + existing_handles: &HashMap, + ) -> Result, Status> { + let mut values_by_storage_key = HashMap::with_capacity(material.len()); + let mut handles_by_storage_key = HashMap::with_capacity(existing_handles.len()); + let mut material_by_storage_key = HashMap::with_capacity(material.len()); + + for (material_key, value) in material { + let storage_key = refresh_material_storage_key(scope.credential_key, material_key); + material_by_storage_key.insert(storage_key.clone(), material_key.clone()); + values_by_storage_key.insert(storage_key, value.clone()); + } + for (material_key, handle) in existing_handles { + handles_by_storage_key.insert( + refresh_material_storage_key(scope.credential_key, material_key), + handle.clone(), + ); + } + + let stored = self + .store_provider_credentials_with_object_id( + scope.provider_name, + scope.workspace, + scope.provider_id, + object_id, + &values_by_storage_key, + &handles_by_storage_key, + ) + .await?; + stored + .into_iter() + .map(|(storage_key, handle)| { + material_by_storage_key + .remove(&storage_key) + .map(|material_key| (material_key, handle)) + .ok_or_else(|| { + Status::internal( + "credential driver returned an unknown refresh material key", + ) + }) + }) + .collect() + } + + pub async fn resolve_refresh_material( + &self, + scope: RefreshMaterialScope<'_>, + handles: &HashMap, + ) -> Result, Status> { + if handles.is_empty() { + return Ok(HashMap::new()); + } + let mut material_by_storage_key = HashMap::with_capacity(handles.len()); + let mut storage_handles = HashMap::with_capacity(handles.len()); + for (material_key, handle) in handles { + let storage_key = refresh_material_storage_key(scope.credential_key, material_key); + material_by_storage_key.insert(storage_key.clone(), material_key.clone()); + storage_handles.insert(storage_key, handle.clone()); + } + let provider = Provider { + metadata: Some(openshell_core::proto::datamodel::v1::ObjectMeta { + id: scope.provider_id.to_string(), + name: scope.provider_name.to_string(), + workspace: scope.workspace.to_string(), + ..Default::default() + }), + credential_handles: storage_handles, + ..Default::default() + }; + let resolved = self.resolve_provider_handles(&provider, 0).await?; + resolved + .values + .into_iter() + .map(|(storage_key, value)| { + material_by_storage_key + .remove(&storage_key) + .map(|material_key| (material_key, value)) + .ok_or_else(|| { + Status::internal( + "credential driver resolved an unknown refresh material key", + ) + }) + }) + .collect() + } + + pub async fn delete_refresh_material_handles( + &self, + scope: RefreshMaterialScope<'_>, + handles: &HashMap, + ) -> Result<(), Status> { + let storage_handles = handles + .iter() + .map(|(material_key, handle)| { + ( + refresh_material_storage_key(scope.credential_key, material_key), + handle.clone(), + ) + }) + .collect(); + self.delete_provider_credential_handles( + scope.provider_name, + scope.workspace, + scope.provider_id, + &storage_handles, + ) + .await + } + pub async fn delete_provider_credential_handles( &self, provider_name: &str, @@ -519,6 +647,16 @@ impl CredentialRuntime { } } +fn refresh_material_storage_key(credential_key: &str, material_key: &str) -> String { + let mut hasher = Sha256::new(); + hasher.update(REFRESH_MATERIAL_CREDENTIAL_KEY_DOMAIN); + hasher.update([0]); + hasher.update(credential_key.as_bytes()); + hasher.update([0]); + hasher.update(material_key.as_bytes()); + format!("openshell.refresh.{:x}", hasher.finalize()) +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum BuiltinCredentialDriverKind { KubernetesSecrets, diff --git a/crates/openshell-server/src/grpc/provider.rs b/crates/openshell-server/src/grpc/provider.rs index 66d66be7fb..2f2c67949f 100644 --- a/crates/openshell-server/src/grpc/provider.rs +++ b/crates/openshell-server/src/grpc/provider.rs @@ -5,6 +5,7 @@ #![allow(clippy::result_large_err)] // gRPC handlers return Result, Status> +use crate::credentials::RefreshMaterialScope; use crate::persistence::{ ObjectId, ObjectLabels, ObjectName, ObjectType, Store, WriteCondition, generate_name, }; @@ -583,6 +584,13 @@ pub(super) async fn delete_provider_record_with_credentials( ))); } + crate::provider_refresh::delete_refresh_states_for_provider_with_credentials( + store, + credentials, + provider.object_id(), + ) + .await?; + credentials .delete_provider_credential_handles( provider.object_name(), @@ -592,9 +600,6 @@ pub(super) async fn delete_provider_record_with_credentials( ) .await?; - crate::provider_refresh::delete_refresh_states_for_provider(store, provider.object_id()) - .await?; - store .delete_by_name(Provider::object_type(), workspace, name) .await @@ -1300,6 +1305,13 @@ fn refresh_authorization_epochs_by_key( ) -> Result, Status> { let mut epochs = HashMap::new(); for state in &record.refresh_states { + if state + .metadata + .as_ref() + .is_some_and(|metadata| metadata.deletion_timestamp_ms != 0) + { + continue; + } if !crate::provider_refresh::is_gateway_mintable_strategy( ProviderCredentialRefreshStrategy::try_from(state.strategy).unwrap_or_default(), ) { @@ -3677,6 +3689,32 @@ pub(super) async fn handle_configure_provider_refresh( &additional_output_keys, )?; validate_refresh_material(&request.material, refresh_defaults.as_ref())?; + let mut secret_material_keys: HashSet = + request.secret_material_keys.iter().cloned().collect(); + for key in &request.secret_material_keys { + if !request.material.contains_key(key) { + return Err(Status::invalid_argument(format!( + "secret_material_keys entry '{key}' is not present in material" + ))); + } + } + if let Some(refresh) = refresh_defaults.as_ref() { + secret_material_keys.extend( + refresh + .material + .iter() + .filter(|item| item.secret && request.material.contains_key(&item.name)) + .map(|item| item.name.clone()), + ); + } + secret_material_keys.extend( + crate::provider_refresh::strategy_secret_material_keys(strategy) + .iter() + .filter(|key| request.material.contains_key(**key)) + .map(|key| (*key).to_string()), + ); + let mut secret_material_keys: Vec<_> = secret_material_keys.into_iter().collect(); + secret_material_keys.sort(); let material_scopes = crate::provider_refresh::material_scopes(&request.material); let token_url = refresh_defaults .as_ref() @@ -3716,27 +3754,88 @@ pub(super) async fn handle_configure_provider_refresh( "max_lifetime_seconds material must be greater than or equal to 0", )); } - let existing_refresh_state = crate::provider_refresh::get_refresh_state( + let mut existing_refresh_state = crate::provider_refresh::get_refresh_state( state.store.as_ref(), &workspace, provider.object_id(), credential_key, ) .await?; + if existing_refresh_state.as_ref().is_some_and(|state| { + state + .metadata + .as_ref() + .is_some_and(|metadata| metadata.deletion_timestamp_ms != 0) + }) { + return Err(Status::failed_precondition( + "provider refresh is being deleted; retry deletion before configuring it again", + )); + } + let existing_refresh_version = existing_refresh_state.as_ref().and_then(|state| { + state + .metadata + .as_ref() + .map(|metadata| metadata.resource_version) + }); + if let Some(existing) = existing_refresh_state.as_mut() + && !existing.pending_secret_deletions.is_empty() + { + state + .credentials + .delete_refresh_material_handles( + RefreshMaterialScope { + provider_name: &existing.provider_name, + workspace: existing.object_workspace(), + provider_id: &existing.provider_id, + credential_key: &existing.credential_key, + }, + &existing.pending_secret_deletions, + ) + .await?; + existing.pending_secret_deletions.clear(); + } let expires_at_ms = request.expires_at_ms.unwrap_or_else(|| { existing_refresh_state .as_ref() .map(|state| state.expires_at_ms) .unwrap_or_default() }); + let mut persisted_material = request.material; + let secret_material: HashMap<_, _> = secret_material_keys + .iter() + .filter_map(|key| { + persisted_material + .remove(key) + .map(|value| (key.clone(), value)) + }) + .collect(); + let material_staging_id = format!( + "{}-refresh-config-{}", + provider.object_id(), + uuid::Uuid::new_v4() + ); + let staged_material_handles = state + .credentials + .store_refresh_material_with_object_id( + RefreshMaterialScope { + provider_name: provider.object_name(), + workspace: &workspace, + provider_id: provider.object_id(), + credential_key, + }, + &material_staging_id, + &secret_material, + &HashMap::new(), + ) + .await?; let mut state_record = crate::provider_refresh::new_refresh_state( &provider, &workspace, credential_key, crate::provider_refresh::NewRefreshStateConfig { strategy, - material: request.material, - secret_material_keys: request.secret_material_keys, + material: persisted_material, + secret_material_keys, expires_at_ms, token_url, scopes, @@ -3745,11 +3844,57 @@ pub(super) async fn handle_configure_provider_refresh( additional_output_keys, }, )?; + state_record.secret_material_handles = staged_material_handles.clone(); if let Some(existing) = existing_refresh_state { state_record.metadata = existing.metadata; state_record.last_refresh_at_ms = existing.last_refresh_at_ms; + state_record + .pending_secret_deletions + .extend(existing.pending_secret_deletions); + state_record + .pending_secret_deletions + .extend(existing.secret_material_handles); + } + let persist_result = if let Some(expected_version) = existing_refresh_version { + match crate::provider_refresh::replace_refresh_state_if_current( + state.store.as_ref(), + &state_record, + expected_version, + ) + .await + { + Ok(true) => Ok(()), + Ok(false) => Err(Status::aborted( + "provider refresh was concurrently modified during configuration", + )), + Err(err) => Err(err), + } + } else { + crate::provider_refresh::put_refresh_state(state.store.as_ref(), &state_record).await + }; + if let Err(err) = persist_result { + if let Err(cleanup_err) = state + .credentials + .delete_refresh_material_handles( + RefreshMaterialScope { + provider_name: provider.object_name(), + workspace: &workspace, + provider_id: provider.object_id(), + credential_key, + }, + &staged_material_handles, + ) + .await + { + warn!( + provider_name = %provider.object_name(), + credential_key, + error = %cleanup_err, + "failed to clean up staged refresh material after configuration failure" + ); + } + return Err(err); } - crate::provider_refresh::put_refresh_state(state.store.as_ref(), &state_record).await?; if let Some(expires_at_ms) = request.expires_at_ms { let updated = Provider { @@ -3889,8 +4034,9 @@ pub(super) async fn handle_delete_provider_refresh( credential_key, ) .await?; - let deleted_refresh_state = crate::provider_refresh::delete_refresh_state( + let deleted_refresh_state = crate::provider_refresh::delete_refresh_state_with_credentials( state.store.as_ref(), + &state.credentials, &workspace, provider.object_id(), credential_key, @@ -5320,6 +5466,7 @@ mod tests { .unwrap() .into_inner(); assert!(deleted.deleted); + assert_eq!(state.credentials.stored_credential_count(), Some(0)); } #[tokio::test] @@ -5686,7 +5833,10 @@ mod tests { ("client_id".to_string(), "client-id".to_string()), ("client_secret".to_string(), "client-secret".to_string()), ]), - secret_material_keys: vec!["client_secret".to_string()], + // The server derives sensitivity from the authoritative + // profile; direct callers cannot opt a client secret out of + // credential storage by omitting this advisory list. + secret_material_keys: Vec::new(), expires_at_ms: Some(expires_at_ms), workspace: "default".to_string(), }), @@ -5734,6 +5884,29 @@ mod tests { .await .unwrap() .expect("first refresh state"); + assert!(!first_refresh.material.contains_key("client_secret")); + assert!( + first_refresh + .secret_material_handles + .contains_key("client_secret") + ); + assert_eq!( + state + .credentials + .resolve_refresh_material( + RefreshMaterialScope { + provider_name: &first_refresh.provider_name, + workspace: first_refresh.object_workspace(), + provider_id: &first_refresh.provider_id, + credential_key: &first_refresh.credential_key, + }, + &first_refresh.secret_material_handles, + ) + .await + .unwrap() + .get("client_secret"), + Some(&"client-secret".to_string()) + ); handle_configure_provider_refresh( &state, authed_request(ConfigureProviderRefreshRequest { @@ -5779,6 +5952,7 @@ mod tests { .unwrap() .into_inner(); assert!(deleted.deleted); + assert_eq!(state.credentials.stored_credential_count(), Some(0)); let status_after_delete = handle_get_provider_refresh_status( &state, diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index ff6e3df596..1f896528e0 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -5,13 +5,14 @@ #![allow(clippy::result_large_err)] +use crate::credentials::RefreshMaterialScope; use crate::persistence::{ObjectType, PersistenceError, Store, WriteCondition, current_time_ms}; use openshell_core::ObjectWorkspace; use openshell_core::proto::{ CredentialHandle, Provider, ProviderCredentialRefreshStatus, ProviderCredentialRefreshStrategy, StoredProviderCredentialRefreshState, }; -use openshell_core::{ObjectId, ObjectName}; +use openshell_core::{ObjectId, ObjectName, SetResourceVersion}; use prost::Message; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -24,6 +25,17 @@ const DEFAULT_MAX_LIFETIME_SECONDS: i64 = 3600; const REFRESH_ERROR_RETRY_SECONDS: i64 = 60; const REFRESH_WORKER_PAGE_SIZE: u32 = 1000; +fn refresh_material_scope( + state: &StoredProviderCredentialRefreshState, +) -> RefreshMaterialScope<'_> { + RefreshMaterialScope { + provider_name: &state.provider_name, + workspace: state.object_workspace(), + provider_id: &state.provider_id, + credential_key: &state.credential_key, + } +} + impl ObjectType for StoredProviderCredentialRefreshState { fn object_type() -> &'static str { "provider_credential_refresh_state" @@ -107,6 +119,18 @@ async fn persist_refresh_state_if_current( } } +pub async fn replace_refresh_state_if_current( + store: &Store, + state: &StoredProviderCredentialRefreshState, + expected_version: u64, +) -> Result { + Ok( + persist_refresh_state_if_current(store, state, expected_version) + .await? + .is_some(), + ) +} + pub async fn list_refresh_states_for_provider( store: &Store, provider_id: &str, @@ -123,11 +147,10 @@ pub async fn list_refresh_states_for_provider( let mut states = Vec::with_capacity(records.len()); for record in records { - states.push( - StoredProviderCredentialRefreshState::decode(record.payload.as_slice()).map_err( - |e| Status::internal(format!("decode provider refresh state failed: {e}")), - )?, - ); + let mut state = StoredProviderCredentialRefreshState::decode(record.payload.as_slice()) + .map_err(|e| Status::internal(format!("decode provider refresh state failed: {e}")))?; + state.set_resource_version(record.resource_version); + states.push(state); } Ok(states) } @@ -138,30 +161,23 @@ pub async fn list_all_refresh_states( let mut states = Vec::new(); let mut offset = 0; loop { - let records = store - .list_by_type( - StoredProviderCredentialRefreshState::object_type(), + let page = store + .list_all_messages::( REFRESH_WORKER_PAGE_SIZE, offset, ) .await .map_err(|e| Status::internal(format!("list provider refresh states failed: {e}")))?; - if records.is_empty() { + if page.is_empty() { break; } offset = offset .checked_add( - u32::try_from(records.len()) + u32::try_from(page.len()) .map_err(|_| Status::internal("provider refresh page size exceeded u32"))?, ) .ok_or_else(|| Status::internal("provider refresh pagination offset overflow"))?; - for record in records { - states.push( - StoredProviderCredentialRefreshState::decode(record.payload.as_slice()).map_err( - |e| Status::internal(format!("decode provider refresh state failed: {e}")), - )?, - ); - } + states.extend(page); } Ok(states) } @@ -179,6 +195,7 @@ pub async fn get_refresh_state( .map_err(|e| Status::internal(format!("fetch provider refresh state failed: {e}"))) } +#[cfg(test)] pub async fn delete_refresh_state( store: &Store, workspace: &str, @@ -196,6 +213,70 @@ pub async fn delete_refresh_state( .map_err(|e| Status::internal(format!("delete provider refresh state failed: {e}"))) } +pub async fn delete_refresh_state_with_credentials( + store: &Store, + credentials: &crate::credentials::CredentialRuntime, + workspace: &str, + provider_id: &str, + credential_key: &str, +) -> Result { + let Some(mut state) = get_refresh_state(store, workspace, provider_id, credential_key).await? + else { + return Ok(false); + }; + let mut version = state + .metadata + .as_ref() + .map_or(0, |metadata| metadata.resource_version); + if state + .metadata + .as_ref() + .is_some_and(|metadata| metadata.deletion_timestamp_ms == 0) + { + if let Some(metadata) = state.metadata.as_mut() { + metadata.deletion_timestamp_ms = current_time_ms(); + } + state.authorization_epoch = uuid::Uuid::new_v4().to_string(); + state.status = "deleting".to_string(); + state.next_refresh_at_ms = i64::MAX; + version = persist_refresh_state_if_current(store, &state, version) + .await? + .ok_or_else(|| { + Status::aborted("provider refresh was concurrently modified during deletion") + })?; + if let Some(metadata) = state.metadata.as_mut() { + metadata.resource_version = version; + } + } + + credentials + .delete_refresh_material_handles( + refresh_material_scope(&state), + &state.pending_secret_deletions, + ) + .await?; + credentials + .delete_refresh_material_handles( + refresh_material_scope(&state), + &state.secret_material_handles, + ) + .await?; + store + .delete_if( + StoredProviderCredentialRefreshState::object_type(), + state.object_id(), + version, + ) + .await + .map_err(|err| match err { + PersistenceError::Conflict { .. } => { + Status::aborted("provider refresh was concurrently modified during deletion") + } + other => Status::internal(format!("delete provider refresh state failed: {other}")), + }) +} + +#[cfg(test)] pub async fn delete_refresh_states_for_provider( store: &Store, provider_id: &str, @@ -218,6 +299,29 @@ pub async fn delete_refresh_states_for_provider( Ok(deleted) } +pub async fn delete_refresh_states_for_provider_with_credentials( + store: &Store, + credentials: &crate::credentials::CredentialRuntime, + provider_id: &str, +) -> Result { + let states = list_refresh_states_for_provider(store, provider_id).await?; + let mut deleted = 0; + for state in &states { + if delete_refresh_state_with_credentials( + store, + credentials, + state.object_workspace(), + provider_id, + &state.credential_key, + ) + .await? + { + deleted += 1; + } + } + Ok(deleted) +} + pub fn refresh_status_from_state( state: &StoredProviderCredentialRefreshState, ) -> ProviderCredentialRefreshStatus { @@ -293,6 +397,8 @@ pub fn new_refresh_state( max_lifetime_seconds: config.max_lifetime_seconds, additional_output_keys: config.additional_output_keys, authorization_epoch: uuid::Uuid::new_v4().to_string(), + secret_material_handles: HashMap::new(), + pending_secret_deletions: HashMap::new(), }) } @@ -362,6 +468,160 @@ pub fn refresh_strategy_name(strategy: i32) -> &'static str { pub use openshell_providers::is_gateway_mintable_strategy; +/// Secret source-material fields that are security-sensitive by strategy even +/// when a direct API caller omits `secret_material_keys`. +pub fn strategy_secret_material_keys( + strategy: ProviderCredentialRefreshStrategy, +) -> &'static [&'static str] { + match strategy { + ProviderCredentialRefreshStrategy::Oauth2RefreshToken => { + &["refresh_token", "client_secret"] + } + ProviderCredentialRefreshStrategy::Oauth2ClientCredentials => &["client_secret"], + ProviderCredentialRefreshStrategy::GoogleServiceAccountJwt => &["private_key"], + ProviderCredentialRefreshStrategy::AwsStsAssumeRole => { + &["aws_secret_access_key", "aws_session_token"] + } + ProviderCredentialRefreshStrategy::Static + | ProviderCredentialRefreshStrategy::External + | ProviderCredentialRefreshStrategy::Unspecified => &[], + } +} + +async fn resolve_refresh_material( + credentials: Option<&crate::credentials::CredentialRuntime>, + state: &StoredProviderCredentialRefreshState, +) -> Result { + if state.secret_material_handles.is_empty() { + return Ok(state.clone()); + } + let credentials = credentials.ok_or_else(|| { + Status::failed_precondition( + "provider refresh material requires the configured credential runtime", + ) + })?; + let resolved = credentials + .resolve_refresh_material( + refresh_material_scope(state), + &state.secret_material_handles, + ) + .await?; + let mut transient = state.clone(); + transient.material.extend(resolved); + Ok(transient) +} + +async fn cleanup_pending_secret_deletions( + store: &Store, + credentials: Option<&crate::credentials::CredentialRuntime>, + state: &mut StoredProviderCredentialRefreshState, + expected_version: u64, +) -> Result { + if state.pending_secret_deletions.is_empty() { + return Ok(expected_version); + } + let credentials = credentials.ok_or_else(|| { + Status::failed_precondition( + "provider refresh cleanup requires the configured credential runtime", + ) + })?; + credentials + .delete_refresh_material_handles( + refresh_material_scope(state), + &state.pending_secret_deletions, + ) + .await?; + state.pending_secret_deletions.clear(); + let new_version = persist_refresh_state_if_current(store, state, expected_version) + .await? + .ok_or_else(|| { + Status::aborted("provider refresh was deleted or superseded during secret cleanup") + })?; + if let Some(metadata) = state.metadata.as_mut() { + metadata.resource_version = new_version; + } + Ok(new_version) +} + +async fn migrate_inline_secret_material( + store: &Store, + credentials: Option<&crate::credentials::CredentialRuntime>, + state: &StoredProviderCredentialRefreshState, +) -> Result { + let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) + .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); + let mut secret_keys: std::collections::HashSet = + state.secret_material_keys.iter().cloned().collect(); + secret_keys.extend( + strategy_secret_material_keys(strategy) + .iter() + .map(|key| (*key).to_string()), + ); + let inline_secrets: HashMap = secret_keys + .into_iter() + .filter_map(|key| state.material.get(&key).cloned().map(|value| (key, value))) + .collect(); + if inline_secrets.is_empty() { + return Ok(state.clone()); + } + let Some(credentials) = credentials else { + // Production refresh entry points always supply the server credential + // runtime. Keeping the no-runtime path readable preserves focused unit + // tests and test-only helpers that exercise minting in isolation. + return Ok(state.clone()); + }; + let values_to_stage: HashMap<_, _> = inline_secrets + .iter() + .filter(|(key, _)| !state.secret_material_handles.contains_key(*key)) + .map(|(key, value)| (key.clone(), value.clone())) + .collect(); + let staging_id = format!( + "{}-refresh-migration-{}", + state.object_id(), + uuid::Uuid::new_v4() + ); + let staged = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(state), + &staging_id, + &values_to_stage, + &HashMap::new(), + ) + .await?; + let mut migrated = state.clone(); + migrated.secret_material_handles.extend(staged.clone()); + for key in inline_secrets.keys() { + migrated.material.remove(key); + if !migrated.secret_material_keys.contains(key) { + migrated.secret_material_keys.push(key.clone()); + } + } + migrated.secret_material_keys.sort(); + migrated.secret_material_keys.dedup(); + let expected_version = state + .metadata + .as_ref() + .map_or(0, |metadata| metadata.resource_version); + match persist_refresh_state_if_current(store, &migrated, expected_version).await { + Ok(Some(new_version)) => { + if let Some(metadata) = migrated.metadata.as_mut() { + metadata.resource_version = new_version; + } + Ok(migrated) + } + Ok(None) => { + cleanup_staged_refresh_material_handles(credentials, state, &staged).await; + Err(Status::aborted( + "provider refresh was deleted or superseded during material migration", + )) + } + Err(err) => { + cleanup_staged_refresh_material_handles(credentials, state, &staged).await; + Err(err) + } + } +} + pub async fn refresh_provider_credential( store: &Store, workspace: &str, @@ -375,11 +635,21 @@ pub async fn refresh_provider_credential( .await .map_err(|e| Status::internal(format!("fetch provider failed: {e}")))? .ok_or_else(|| Status::not_found("provider not found"))?; - let Some(mut state) = + let Some(state) = get_refresh_state(store, workspace, provider.object_id(), credential_key).await? else { return Err(Status::not_found("provider refresh state not found")); }; + if state + .metadata + .as_ref() + .is_some_and(|metadata| metadata.deletion_timestamp_ms != 0) + { + return Err(Status::failed_precondition( + "provider refresh is being deleted", + )); + } + let mut state = migrate_inline_secret_material(store, credentials, &state).await?; // Generation of the refresh at the start of the rotation. Terminal persists // match on it so a concurrent delete or rotation is detected rather than // clobbered, and a deleted refresh is never recreated (CWE-362). @@ -387,6 +657,8 @@ pub async fn refresh_provider_credential( .metadata .as_ref() .map_or(0, |meta| meta.resource_version); + let expected_version = + cleanup_pending_secret_deletions(store, credentials, &mut state, expected_version).await?; info!( provider = %state.provider_name, @@ -419,13 +691,15 @@ pub async fn refresh_provider_credential( return Err(err); } - match mint_credential(&state).await { + let mint_result = match resolve_refresh_material(credentials, &state).await { + Ok(transient_state) => mint_credential(&transient_state).await, + Err(err) => Err(err), + }; + match mint_result { Ok(minted) => { let now_ms = current_time_ms(); + let mut staged_refresh_token_handles = HashMap::new(); if let Some(ref refresh_token) = minted.refresh_token { - state - .material - .insert("refresh_token".to_string(), refresh_token.clone()); if !state .secret_material_keys .iter() @@ -433,6 +707,46 @@ pub async fn refresh_provider_credential( { state.secret_material_keys.push("refresh_token".to_string()); } + if let Some(credentials) = credentials { + let material = + HashMap::from([("refresh_token".to_string(), refresh_token.clone())]); + let staging_id = format!( + "{}-refresh-material-{}", + state.object_id(), + uuid::Uuid::new_v4() + ); + staged_refresh_token_handles = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + &staging_id, + &material, + &HashMap::new(), + ) + .await?; + let handle = staged_refresh_token_handles + .get("refresh_token") + .cloned() + .ok_or_else(|| { + Status::internal( + "credential driver did not return a refresh-token handle", + ) + })?; + if let Some(previous) = state + .secret_material_handles + .insert("refresh_token".to_string(), handle) + { + state + .pending_secret_deletions + .insert("refresh_token".to_string(), previous); + } + state.material.remove("refresh_token"); + } else { + // Test-only and legacy callers without a credential runtime + // retain the pre-driver behavior. + state + .material + .insert("refresh_token".to_string(), refresh_token.clone()); + } } state.expires_at_ms = minted.expires_at_ms; state.next_refresh_at_ms = next_refresh_at_ms( @@ -453,18 +767,48 @@ pub async fn refresh_provider_credential( // from a stale generation are written, and a deleted refresh is not // resurrected (CWE-362). This makes generation ownership the gate on // the provider credential write. - let Some(new_version) = - persist_refresh_state_if_current(store, &state, expected_version).await? - else { - warn!( - provider = %state.provider_name, - credential_key = %state.credential_key, - strategy = %refresh_strategy_name(state.strategy), - "provider credential refresh deleted or superseded during rotation; discarding minted credentials" - ); - return Err(Status::aborted( - "provider refresh was deleted or superseded during rotation", - )); + let new_version = match persist_refresh_state_if_current( + store, + &state, + expected_version, + ) + .await + { + Ok(Some(new_version)) => new_version, + Ok(None) => { + if let Some(credentials) = credentials + && !staged_refresh_token_handles.is_empty() + { + cleanup_staged_refresh_material_handles( + credentials, + &state, + &staged_refresh_token_handles, + ) + .await; + } + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + strategy = %refresh_strategy_name(state.strategy), + "provider credential refresh deleted or superseded during rotation; discarding minted credentials" + ); + return Err(Status::aborted( + "provider refresh was deleted or superseded during rotation", + )); + } + Err(err) => { + if let Some(credentials) = credentials + && !staged_refresh_token_handles.is_empty() + { + cleanup_staged_refresh_material_handles( + credentials, + &state, + &staged_refresh_token_handles, + ) + .await; + } + return Err(err); + } }; // Generation is ours; write the minted credentials into the provider. @@ -508,6 +852,18 @@ pub async fn refresh_provider_credential( seconds_until_refresh = seconds_until_ms(now_ms, state.next_refresh_at_ms), "provider credential refresh completed" ); + if !state.pending_secret_deletions.is_empty() + && let Err(err) = + cleanup_pending_secret_deletions(store, credentials, &mut state, new_version) + .await + { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + error = %err, + "failed to clean up replaced refresh material; retrying on the next sweep" + ); + } Ok(state) } Err(err) => { @@ -532,6 +888,24 @@ pub async fn refresh_provider_credential( } } +async fn cleanup_staged_refresh_material_handles( + credentials: &crate::credentials::CredentialRuntime, + state: &StoredProviderCredentialRefreshState, + handles: &HashMap, +) { + if let Err(err) = credentials + .delete_refresh_material_handles(refresh_material_scope(state), handles) + .await + { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + error = %err, + "failed to clean up staged provider refresh material" + ); + } +} + async fn apply_minted_credential( store: &Store, workspace: &str, @@ -1192,6 +1566,40 @@ async fn run_refresh_worker_tick( due_count, rotation_requested_count, "provider credential refresh worker sweep" ); for state in states { + let mut state = match migrate_inline_secret_material(store, credentials, &state).await { + Ok(state) => state, + Err(err) => { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + error = %err, + "provider refresh material migration failed" + ); + continue; + } + }; + let expected_version = state + .metadata + .as_ref() + .map_or(0, |metadata| metadata.resource_version); + if let Err(err) = + cleanup_pending_secret_deletions(store, credentials, &mut state, expected_version).await + { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + error = %err, + "provider refresh material cleanup failed" + ); + continue; + } + if state + .metadata + .as_ref() + .is_some_and(|metadata| metadata.deletion_timestamp_ms != 0) + { + continue; + } let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); let due = state.next_refresh_at_ms <= 0 || state.next_refresh_at_ms <= now_ms; @@ -1258,8 +1666,9 @@ async fn run_refresh_worker_tick( mod tests { use super::{ NewRefreshStateConfig, delete_refresh_state, effective_authorization_epoch, - get_refresh_state, new_refresh_state, put_refresh_state, refresh_provider_credential, - refresh_state_name, refresh_strategy_name, run_refresh_worker_tick, seconds_until_ms, + get_refresh_state, list_all_refresh_states, list_refresh_states_for_provider, + new_refresh_state, put_refresh_state, refresh_provider_credential, refresh_state_name, + refresh_strategy_name, run_refresh_worker_tick, seconds_until_ms, }; use crate::credentials::CredentialRuntime; use crate::persistence::{current_time_ms, test_store}; @@ -1267,6 +1676,7 @@ mod tests { use openshell_core::proto::datamodel::v1::ObjectMeta; use openshell_core::proto::{ Provider, ProviderCredentialRefreshStrategy, Sandbox, SandboxSpec, + StoredProviderCredentialRefreshState, }; use openshell_core::{ObjectId, ObjectName, ObjectWorkspace}; use std::collections::HashMap; @@ -1291,6 +1701,31 @@ mod tests { ); } + #[tokio::test] + async fn refresh_state_lists_hydrate_authoritative_resource_versions() { + let store = test_store().await; + let provider_id = "provider-id"; + let state = StoredProviderCredentialRefreshState { + metadata: Some(ObjectMeta { + id: "refresh-id".to_string(), + name: refresh_state_name(provider_id, "ACCESS_TOKEN"), + workspace: "default".to_string(), + ..Default::default() + }), + provider_id: provider_id.to_string(), + credential_key: "ACCESS_TOKEN".to_string(), + ..Default::default() + }; + put_refresh_state(&store, &state).await.unwrap(); + + let scoped = list_refresh_states_for_provider(&store, provider_id) + .await + .unwrap(); + let all = list_all_refresh_states(&store).await.unwrap(); + assert_eq!(scoped[0].metadata.as_ref().unwrap().resource_version, 1); + assert_eq!(all[0].metadata.as_ref().unwrap().resource_version, 1); + } + #[test] fn new_refresh_configuration_rotates_authorization_epoch_and_legacy_state_is_stable() { let provider = Provider { @@ -1481,6 +1916,21 @@ mod tests { .await .unwrap(); assert_eq!(refreshed.authorization_epoch, authorization_epoch); + let stored_refresh = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert!(!stored_refresh.material.contains_key("client_secret")); + assert!( + stored_refresh + .secret_material_handles + .contains_key("client_secret") + ); let stored = store .get_message_by_name::("default", "my-stored-graph") @@ -1652,11 +2102,15 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = CredentialRuntime::from_config( + &Config::new(None).with_credential_drivers(["test-static"]), + ) + .unwrap(); let refreshed = refresh_provider_credential( &store, "default", - None, + Some(&credentials), None, "my-delegated-graph", "MS_GRAPH_ACCESS_TOKEN", @@ -1671,9 +2125,15 @@ mod tests { .await .unwrap() .unwrap(); - assert_eq!( - stored_provider.credentials.get("MS_GRAPH_ACCESS_TOKEN"), - Some(&"delegated-graph-token".to_string()) + assert!( + !stored_provider + .credentials + .contains_key("MS_GRAPH_ACCESS_TOKEN") + ); + assert!( + stored_provider + .credential_handles + .contains_key("MS_GRAPH_ACCESS_TOKEN") ); assert_eq!( stored_provider @@ -1691,8 +2151,22 @@ mod tests { .await .unwrap() .unwrap(); + assert!(!stored_state.material.contains_key("refresh_token")); + assert!( + stored_state + .secret_material_handles + .contains_key("refresh_token") + ); + assert!(stored_state.pending_secret_deletions.is_empty()); assert_eq!( - stored_state.material.get("refresh_token"), + credentials + .resolve_refresh_material( + super::refresh_material_scope(&stored_state), + &stored_state.secret_material_handles, + ) + .await + .unwrap() + .get("refresh_token"), Some(&"rotated-refresh-token".to_string()) ); assert!( @@ -1701,6 +2175,11 @@ mod tests { .iter() .any(|key| key == "refresh_token") ); + assert_eq!( + credentials.stored_credential_count(), + Some(2), + "only the access token and current refresh token remain" + ); } #[tokio::test] diff --git a/docs/reference/gateway-config.mdx b/docs/reference/gateway-config.mdx index 8d74b3d44f..402db6dab4 100644 --- a/docs/reference/gateway-config.mdx +++ b/docs/reference/gateway-config.mdx @@ -331,7 +331,7 @@ The gateway validates snapshot structure and provider-profile semantics. It trea ## Credential Drivers -Set `credential_drivers` only when the gateway should store provider credentials in an external credential backend. OpenShell supports at most one enabled credential driver at a time. When `credential_drivers` is omitted, the gateway uses its default encrypted database credential storage. `credential_drivers = []` is invalid in the TOML file; omit the field for the default encrypted store, or select a backend such as `kubernetes-secrets` or `vault`. +Set `credential_drivers` only when the gateway should store provider secrets in an external credential backend. Provider secrets include injectable credentials and gateway-only refresh material such as OAuth refresh tokens, client secrets, and service-account private keys. OpenShell supports at most one enabled credential driver at a time. When `credential_drivers` is omitted, the gateway uses its default encrypted database credential storage. `credential_drivers = []` is invalid in the TOML file; omit the field for the default encrypted store, or select a backend such as `kubernetes-secrets` or `vault`. Credential driver tables are backend-owned and live under `[openshell.credential_drivers.]`. Built-in drivers default to in-tree transport, so they do not need a `transport` field. Use `transport = "uds"` with an absolute `socket_path` only for a remote gRPC driver over a Unix domain socket. @@ -379,7 +379,7 @@ For `kubernetes-secrets`, `namespace` sets where OpenShell-managed provider Secr For `vault`, `address` points at the Vault service, `mount` and `kv_version` describe the KV engine where OpenShell-managed provider secrets are stored, and `auth_method = "kubernetes"` logs in with the gateway Pod's ServiceAccount token. For local or development validation, use `auth_method = "token_file"` with `token_path = "/path/to/token"`. Do not put literal Vault tokens in TOML. -Provider records that already contain inline database credentials remain readable for upgrade compatibility. New provider create/update requests still submit credential values through the normal API, but the gateway stores those values through the active credential storage path and persists only handles. +Provider records that already contain inline database credentials remain readable for upgrade compatibility. New provider create/update requests still submit credential values through the normal API, but the gateway stores those values through the active credential storage path and persists only handles. The refresh worker migrates legacy inline secret refresh material to the same storage path before minting. Stop all older gateway replicas before starting the version that performs this migration; older protobuf runtimes do not preserve the new internal handle fields when they rewrite refresh state. For remote credential drivers, set `transport = "uds"` with `socket_path`. Omit `command`, `args`, and `startup_timeout_secs` when another service manager prestarts the driver socket. Keep backend tokens out of TOML; point the driver at mounted token files or native identity mechanisms instead. diff --git a/docs/sandboxes/providers-v2.mdx b/docs/sandboxes/providers-v2.mdx index 9395de3156..9aa282a4a3 100644 --- a/docs/sandboxes/providers-v2.mdx +++ b/docs/sandboxes/providers-v2.mdx @@ -573,10 +573,12 @@ openshell provider create \ --credential OPENAI_API_KEY ``` -The create/update API stores submitted provider credentials through the -gateway's active credential storage path and persists only internal credential -handles. By default, the gateway stores AES-256-GCM encrypted credential -envelopes in the gateway database outside the provider record. The Helm chart +The create/update API stores submitted provider credentials and secret refresh +material through the gateway's active credential storage path and persists only +internal credential handles. Secret refresh material includes OAuth refresh +tokens, client secrets, service-account private keys, and temporary AWS source +secrets. By default, the gateway stores AES-256-GCM encrypted credential +envelopes in the gateway database outside provider and refresh-state records. The Helm chart creates a retained Kubernetes Secret for the default storage key-encryption key and injects it into every gateway pod when no external credential driver is enabled. `credential_drivers = []` is invalid. Multi-replica Kubernetes gateways can use @@ -617,7 +619,16 @@ The gateway sends a complete host, port, and path binding for every emitted stat ## Configure Credential Refresh -Refresh configuration is stored separately from the current injectable credential value. The gateway refresh worker reads refresh state, mints a new short-lived token for supported strategies, writes the token back to the provider record, and updates credential expiry metadata. +Refresh configuration is stored separately from the current injectable credential value. Non-secret refresh configuration remains in the refresh-state record. Secret material is resolved from the active credential driver only while the gateway mints a new short-lived token. The gateway writes the token back through credential storage and updates credential expiry metadata. If an OAuth issuer rotates its refresh token, the gateway stages the replacement through credential storage before committing the refresh generation and removes the previous handle afterward. + +On upgrade, the refresh worker migrates legacy inline secret material before it +mints again. For a multi-replica gateway, stop every older replica before the +new version begins migration. A normal mixed-version rolling update is unsafe +because older protobuf runtimes can discard internal handle fields when they +rewrite refresh state. Migration removes plaintext values from current records, +but database backups, SQLite WAL/free pages, and Postgres dead tuples may retain +historical bytes. Rotate the upstream grant and apply the database's retention +or compaction procedure when historical erasure is required. Each explicit `refresh configure` call also starts a new gateway-owned authorization epoch. Automatic refresh and `refresh rotate` preserve that epoch, @@ -701,7 +712,7 @@ openshell provider refresh configure drive-work \ This example assumes you imported a custom profile with `id: google-drive`. -`--secret-material-key` takes the name of a `--material` key, not the secret value. For example, use `--material client_secret="$MS_CLIENT_SECRET"` with `--secret-material-key client_secret`. The key should match a material entry so OpenShell can record that material field as sensitive when it stores refresh state. The gateway uses the material values to mint future access tokens, but only the `--credential-key` value, such as `MS_GRAPH_ACCESS_TOKEN`, becomes the injectable provider credential. If a refresh response rotates an OAuth refresh token, OpenShell stores the new `refresh_token` material and marks `refresh_token` as secret automatically. +`--secret-material-key` takes the name of a `--material` key, not the secret value. For example, use `--material client_secret="$MS_CLIENT_SECRET"` with `--secret-material-key client_secret`. Prefer `--secret-material-env` so the value does not appear in shell history. The gateway combines caller markings with authoritative profile metadata and strategy-defined secret fields, then stores those values through the active credential driver. Only the `--credential-key` value, such as `MS_GRAPH_ACCESS_TOKEN`, becomes injectable. If an OAuth response rotates a refresh token, OpenShell stores the replacement through the credential driver automatically. Use `--credential-expires-at` when the current provider credential already has a known expiry timestamp. For refresh-managed keys, the value can be Unix epoch milliseconds or an ISO/RFC3339 timestamp such as `2026-01-01T00:00:00Z` or `2026-01-01T01:00:00+01:00`. OpenShell stores that value as epoch milliseconds in both refresh state and provider credential metadata. Later gateway-managed refreshes replace it with the minted token expiry. diff --git a/proto/credential_driver.proto b/proto/credential_driver.proto index 471bf033bc..b25e9256d0 100644 --- a/proto/credential_driver.proto +++ b/proto/credential_driver.proto @@ -11,13 +11,14 @@ import "datamodel.proto"; // // The gateway owns provider semantics and sandbox delivery. Credential drivers // own backend-specific storage, deletion, authentication, and lookup for -// gateway-managed credential handles. +// gateway-managed provider-secret handles. Secrets include injectable provider +// credentials and gateway-only refresh material. service CredentialDriver { // Report driver identity and feature support. rpc GetCapabilities(GetCredentialDriverCapabilitiesRequest) returns (GetCredentialDriverCapabilitiesResponse); - // Store or overwrite one provider credential and return an opaque handle. + // Store or overwrite one gateway-managed provider secret and return an opaque handle. rpc StoreCredential(StoreCredentialRequest) returns (StoreCredentialResponse); // Delete one provider credential handle. @@ -49,7 +50,8 @@ message GetCredentialDriverCapabilitiesResponse { message StoreCredentialRequest { // Provider instance name supplied for audit and backend policy decisions. string provider_name = 1; - // Provider credential key that will receive the resolved value at runtime. + // Gateway-owned logical key for this provider secret. Injectable credentials + // use their runtime environment key; refresh material uses an internal key. string credential_key = 2; // Secret value to store. Drivers must never log this field. string value = 3; @@ -73,7 +75,7 @@ message StoreCredentialResponse { message DeleteCredentialRequest { // Provider instance name supplied for audit and backend policy decisions. string provider_name = 1; - // Provider credential key that owns the handle. + // Gateway-owned logical key that owns the handle. string credential_key = 2; // Opaque handle to delete. openshell.datamodel.v1.CredentialHandle handle = 3; @@ -94,7 +96,7 @@ message ResolveCredentialRequest { string request_id = 1; // Provider instance name supplied for audit and backend policy decisions. string provider_name = 2; - // Provider credential key that will receive the resolved value. + // Gateway-owned logical key for the value being resolved. string credential_key = 3; // Opaque handle to resolve. openshell.datamodel.v1.CredentialHandle handle = 4; diff --git a/proto/openshell.proto b/proto/openshell.proto index 6d756721f6..f804aae695 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -1579,6 +1579,8 @@ message StoredProviderCredentialRefreshState { string credential_key = 4; ProviderCredentialRefreshStrategy strategy = 5; map material = 6 [(openshell.options.v1.secret) = true]; + // Material names classified as secret. Their values live in the active + // credential driver and are absent from material after migration. repeated string secret_material_keys = 7; int64 expires_at_ms = 8; int64 next_refresh_at_ms = 9; @@ -1599,6 +1601,14 @@ message StoredProviderCredentialRefreshState { // manual token rotation preserve it. It is never derived from or exposed // with refresh material. string authorization_epoch = 18; + // Secret refresh material is stored through the gateway's active credential + // driver. The persisted refresh state keeps only opaque handles; resolved + // values exist in gateway memory for the duration of one mint operation. + map secret_material_handles = 19; + // Handles replaced by reconfiguration or issuer-driven refresh-token + // rotation. Cleanup is retried by the refresh worker so a gateway crash or + // temporary credential-backend outage does not lose the deletion reference. + map pending_secret_deletions = 20; } message GetProviderRefreshStatusRequest { @@ -1617,6 +1627,9 @@ message ConfigureProviderRefreshRequest { string credential_key = 2; ProviderCredentialRefreshStrategy strategy = 3; map material = 4 [(openshell.options.v1.secret) = true]; + // Additional material names the caller requests be stored as secrets. Every + // name must be present in material. The server also classifies secrets from + // the authoritative provider profile and refresh strategy. repeated string secret_material_keys = 5; optional int64 expires_at_ms = 6; // Workspace scope. Empty defaults to "default". diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index acf7d6554e..bf3e9577bd 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -5832,23 +5832,25 @@ func (x *ProviderProfileDiscovery) GetCredentials() []string { } type StoredProviderCredentialRefreshState struct { - state protoimpl.MessageState `protogen:"open.v1"` - Metadata *datamodelv1.ObjectMeta `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` - ProviderId string `protobuf:"bytes,2,opt,name=provider_id,json=providerId,proto3" json:"provider_id,omitempty"` - ProviderName string `protobuf:"bytes,3,opt,name=provider_name,json=providerName,proto3" json:"provider_name,omitempty"` - CredentialKey string `protobuf:"bytes,4,opt,name=credential_key,json=credentialKey,proto3" json:"credential_key,omitempty"` - Strategy ProviderCredentialRefreshStrategy `protobuf:"varint,5,opt,name=strategy,proto3,enum=openshell.v1.ProviderCredentialRefreshStrategy" json:"strategy,omitempty"` - Material map[string]string `protobuf:"bytes,6,rep,name=material,proto3" json:"material,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - SecretMaterialKeys []string `protobuf:"bytes,7,rep,name=secret_material_keys,json=secretMaterialKeys,proto3" json:"secret_material_keys,omitempty"` - ExpiresAtMs int64 `protobuf:"varint,8,opt,name=expires_at_ms,json=expiresAtMs,proto3" json:"expires_at_ms,omitempty"` - NextRefreshAtMs int64 `protobuf:"varint,9,opt,name=next_refresh_at_ms,json=nextRefreshAtMs,proto3" json:"next_refresh_at_ms,omitempty"` - LastRefreshAtMs int64 `protobuf:"varint,10,opt,name=last_refresh_at_ms,json=lastRefreshAtMs,proto3" json:"last_refresh_at_ms,omitempty"` - Status string `protobuf:"bytes,11,opt,name=status,proto3" json:"status,omitempty"` - LastError string `protobuf:"bytes,12,opt,name=last_error,json=lastError,proto3" json:"last_error,omitempty"` - TokenUrl string `protobuf:"bytes,13,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"` - Scopes []string `protobuf:"bytes,14,rep,name=scopes,proto3" json:"scopes,omitempty"` - RefreshBeforeSeconds int64 `protobuf:"varint,15,opt,name=refresh_before_seconds,json=refreshBeforeSeconds,proto3" json:"refresh_before_seconds,omitempty"` - MaxLifetimeSeconds int64 `protobuf:"varint,16,opt,name=max_lifetime_seconds,json=maxLifetimeSeconds,proto3" json:"max_lifetime_seconds,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Metadata *datamodelv1.ObjectMeta `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + ProviderId string `protobuf:"bytes,2,opt,name=provider_id,json=providerId,proto3" json:"provider_id,omitempty"` + ProviderName string `protobuf:"bytes,3,opt,name=provider_name,json=providerName,proto3" json:"provider_name,omitempty"` + CredentialKey string `protobuf:"bytes,4,opt,name=credential_key,json=credentialKey,proto3" json:"credential_key,omitempty"` + Strategy ProviderCredentialRefreshStrategy `protobuf:"varint,5,opt,name=strategy,proto3,enum=openshell.v1.ProviderCredentialRefreshStrategy" json:"strategy,omitempty"` + Material map[string]string `protobuf:"bytes,6,rep,name=material,proto3" json:"material,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Material names classified as secret. Their values live in the active + // credential driver and are absent from material after migration. + SecretMaterialKeys []string `protobuf:"bytes,7,rep,name=secret_material_keys,json=secretMaterialKeys,proto3" json:"secret_material_keys,omitempty"` + ExpiresAtMs int64 `protobuf:"varint,8,opt,name=expires_at_ms,json=expiresAtMs,proto3" json:"expires_at_ms,omitempty"` + NextRefreshAtMs int64 `protobuf:"varint,9,opt,name=next_refresh_at_ms,json=nextRefreshAtMs,proto3" json:"next_refresh_at_ms,omitempty"` + LastRefreshAtMs int64 `protobuf:"varint,10,opt,name=last_refresh_at_ms,json=lastRefreshAtMs,proto3" json:"last_refresh_at_ms,omitempty"` + Status string `protobuf:"bytes,11,opt,name=status,proto3" json:"status,omitempty"` + LastError string `protobuf:"bytes,12,opt,name=last_error,json=lastError,proto3" json:"last_error,omitempty"` + TokenUrl string `protobuf:"bytes,13,opt,name=token_url,json=tokenUrl,proto3" json:"token_url,omitempty"` + Scopes []string `protobuf:"bytes,14,rep,name=scopes,proto3" json:"scopes,omitempty"` + RefreshBeforeSeconds int64 `protobuf:"varint,15,opt,name=refresh_before_seconds,json=refreshBeforeSeconds,proto3" json:"refresh_before_seconds,omitempty"` + MaxLifetimeSeconds int64 `protobuf:"varint,16,opt,name=max_lifetime_seconds,json=maxLifetimeSeconds,proto3" json:"max_lifetime_seconds,omitempty"` // Resolved mapping of strategy-defined output id -> concrete env key, pinned // at configure time from the profile's additional_outputs. Read by minting, // collision reservation, and env-key surfacing so later profile edits cannot @@ -5859,8 +5861,16 @@ type StoredProviderCredentialRefreshState struct { // manual token rotation preserve it. It is never derived from or exposed // with refresh material. AuthorizationEpoch string `protobuf:"bytes,18,opt,name=authorization_epoch,json=authorizationEpoch,proto3" json:"authorization_epoch,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // Secret refresh material is stored through the gateway's active credential + // driver. The persisted refresh state keeps only opaque handles; resolved + // values exist in gateway memory for the duration of one mint operation. + SecretMaterialHandles map[string]*datamodelv1.CredentialHandle `protobuf:"bytes,19,rep,name=secret_material_handles,json=secretMaterialHandles,proto3" json:"secret_material_handles,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Handles replaced by reconfiguration or issuer-driven refresh-token + // rotation. Cleanup is retried by the refresh worker so a gateway crash or + // temporary credential-backend outage does not lose the deletion reference. + PendingSecretDeletions map[string]*datamodelv1.CredentialHandle `protobuf:"bytes,20,rep,name=pending_secret_deletions,json=pendingSecretDeletions,proto3" json:"pending_secret_deletions,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StoredProviderCredentialRefreshState) Reset() { @@ -6019,6 +6029,20 @@ func (x *StoredProviderCredentialRefreshState) GetAuthorizationEpoch() string { return "" } +func (x *StoredProviderCredentialRefreshState) GetSecretMaterialHandles() map[string]*datamodelv1.CredentialHandle { + if x != nil { + return x.SecretMaterialHandles + } + return nil +} + +func (x *StoredProviderCredentialRefreshState) GetPendingSecretDeletions() map[string]*datamodelv1.CredentialHandle { + if x != nil { + return x.PendingSecretDeletions + } + return nil +} + type GetProviderRefreshStatusRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` @@ -6125,13 +6149,16 @@ func (x *GetProviderRefreshStatusResponse) GetCredentials() []*ProviderCredentia } type ConfigureProviderRefreshRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` - CredentialKey string `protobuf:"bytes,2,opt,name=credential_key,json=credentialKey,proto3" json:"credential_key,omitempty"` - Strategy ProviderCredentialRefreshStrategy `protobuf:"varint,3,opt,name=strategy,proto3,enum=openshell.v1.ProviderCredentialRefreshStrategy" json:"strategy,omitempty"` - Material map[string]string `protobuf:"bytes,4,rep,name=material,proto3" json:"material,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - SecretMaterialKeys []string `protobuf:"bytes,5,rep,name=secret_material_keys,json=secretMaterialKeys,proto3" json:"secret_material_keys,omitempty"` - ExpiresAtMs *int64 `protobuf:"varint,6,opt,name=expires_at_ms,json=expiresAtMs,proto3,oneof" json:"expires_at_ms,omitempty"` + state protoimpl.MessageState `protogen:"open.v1"` + Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + CredentialKey string `protobuf:"bytes,2,opt,name=credential_key,json=credentialKey,proto3" json:"credential_key,omitempty"` + Strategy ProviderCredentialRefreshStrategy `protobuf:"varint,3,opt,name=strategy,proto3,enum=openshell.v1.ProviderCredentialRefreshStrategy" json:"strategy,omitempty"` + Material map[string]string `protobuf:"bytes,4,rep,name=material,proto3" json:"material,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Additional material names the caller requests be stored as secrets. Every + // name must be present in material. The server also classifies secrets from + // the authoritative provider profile and refresh strategy. + SecretMaterialKeys []string `protobuf:"bytes,5,rep,name=secret_material_keys,json=secretMaterialKeys,proto3" json:"secret_material_keys,omitempty"` + ExpiresAtMs *int64 `protobuf:"varint,6,opt,name=expires_at_ms,json=expiresAtMs,proto3,oneof" json:"expires_at_ms,omitempty"` // Workspace scope. Empty defaults to "default". Workspace string `protobuf:"bytes,7,opt,name=workspace,proto3" json:"workspace,omitempty"` unknownFields protoimpl.UnknownFields @@ -13506,7 +13533,7 @@ const file_openshell_proto_rawDesc = "" + "\n" + "last_error\x18\t \x01(\tR\tlastError\"<\n" + "\x18ProviderProfileDiscovery\x12 \n" + - "\vcredentials\x18\x01 \x03(\tR\vcredentials\"\xc4\b\n" + + "\vcredentials\x18\x01 \x03(\tR\vcredentials\"\xc0\f\n" + "$StoredProviderCredentialRefreshState\x12>\n" + "\bmetadata\x18\x01 \x01(\v2\".openshell.datamodel.v1.ObjectMetaR\bmetadata\x12\x1f\n" + "\vprovider_id\x18\x02 \x01(\tR\n" + @@ -13528,13 +13555,21 @@ const file_openshell_proto_rawDesc = "" + "\x16refresh_before_seconds\x18\x0f \x01(\x03R\x14refreshBeforeSeconds\x120\n" + "\x14max_lifetime_seconds\x18\x10 \x01(\x03R\x12maxLifetimeSeconds\x12\x82\x01\n" + "\x16additional_output_keys\x18\x11 \x03(\v2L.openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntryR\x14additionalOutputKeys\x12/\n" + - "\x13authorization_epoch\x18\x12 \x01(\tR\x12authorizationEpoch\x1a;\n" + + "\x13authorization_epoch\x18\x12 \x01(\tR\x12authorizationEpoch\x12\x85\x01\n" + + "\x17secret_material_handles\x18\x13 \x03(\v2M.openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntryR\x15secretMaterialHandles\x12\x88\x01\n" + + "\x18pending_secret_deletions\x18\x14 \x03(\v2N.openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntryR\x16pendingSecretDeletions\x1a;\n" + "\rMaterialEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1aG\n" + "\x19AdditionalOutputKeysEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + - "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x82\x01\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1ar\n" + + "\x1aSecretMaterialHandlesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12>\n" + + "\x05value\x18\x02 \x01(\v2(.openshell.datamodel.v1.CredentialHandleR\x05value:\x028\x01\x1as\n" + + "\x1bPendingSecretDeletionsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12>\n" + + "\x05value\x18\x02 \x01(\v2(.openshell.datamodel.v1.CredentialHandleR\x05value:\x028\x01\"\x82\x01\n" + "\x1fGetProviderRefreshStatusRequest\x12\x1a\n" + "\bprovider\x18\x01 \x01(\tR\bprovider\x12%\n" + "\x0ecredential_key\x18\x02 \x01(\tR\rcredentialKey\x12\x1c\n" + @@ -14286,7 +14321,7 @@ func file_openshell_proto_rawDescGZIP() []byte { } var file_openshell_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 209) +var file_openshell_proto_msgTypes = make([]protoimpl.MessageInfo, 211) var file_openshell_proto_goTypes = []any{ (SandboxPhase)(0), // 0: openshell.v1.SandboxPhase (ProviderCredentialRefreshStrategy)(0), // 1: openshell.v1.ProviderCredentialRefreshStrategy @@ -14491,33 +14526,36 @@ var file_openshell_proto_goTypes = []any{ nil, // 200: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry nil, // 201: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry nil, // 202: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - nil, // 203: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - nil, // 204: openshell.v1.ProviderProfile.AnnotationsEntry - nil, // 205: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - nil, // 206: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - nil, // 207: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - nil, // 208: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - nil, // 209: openshell.v1.UpdateConfigRequest.AnnotationsEntry - nil, // 210: openshell.v1.UpdateConfigResponse.AnnotationsEntry - nil, // 211: openshell.v1.SandboxPolicyRevision.ProvenanceEntry - nil, // 212: openshell.v1.PolicyRevisionPayload.ProvenanceEntry - nil, // 213: openshell.v1.StoredPolicyRevision.ProvenanceEntry - nil, // 214: openshell.v1.CreateWorkspaceRequest.LabelsEntry - (*datamodelv1.ObjectMeta)(nil), // 215: openshell.datamodel.v1.ObjectMeta - (*sandboxv1.SandboxPolicy)(nil), // 216: openshell.sandbox.v1.SandboxPolicy - (*structpb.Struct)(nil), // 217: google.protobuf.Struct - (*datamodelv1.Provider)(nil), // 218: openshell.datamodel.v1.Provider - (*sandboxv1.NetworkEndpoint)(nil), // 219: openshell.sandbox.v1.NetworkEndpoint - (*sandboxv1.NetworkBinary)(nil), // 220: openshell.sandbox.v1.NetworkBinary - (*sandboxv1.SettingValue)(nil), // 221: openshell.sandbox.v1.SettingValue - (*sandboxv1.NetworkPolicyRule)(nil), // 222: openshell.sandbox.v1.NetworkPolicyRule - (*sandboxv1.L7DenyRule)(nil), // 223: openshell.sandbox.v1.L7DenyRule - (*sandboxv1.L7Rule)(nil), // 224: openshell.sandbox.v1.L7Rule - (*datamodelv1.Workspace)(nil), // 225: openshell.datamodel.v1.Workspace - (*sandboxv1.GetSandboxConfigRequest)(nil), // 226: openshell.sandbox.v1.GetSandboxConfigRequest - (*sandboxv1.GetGatewayConfigRequest)(nil), // 227: openshell.sandbox.v1.GetGatewayConfigRequest - (*sandboxv1.GetSandboxConfigResponse)(nil), // 228: openshell.sandbox.v1.GetSandboxConfigResponse - (*sandboxv1.GetGatewayConfigResponse)(nil), // 229: openshell.sandbox.v1.GetGatewayConfigResponse + nil, // 203: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry + nil, // 204: openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntry + nil, // 205: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + nil, // 206: openshell.v1.ProviderProfile.AnnotationsEntry + nil, // 207: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + nil, // 208: openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + nil, // 209: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + nil, // 210: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + nil, // 211: openshell.v1.UpdateConfigRequest.AnnotationsEntry + nil, // 212: openshell.v1.UpdateConfigResponse.AnnotationsEntry + nil, // 213: openshell.v1.SandboxPolicyRevision.ProvenanceEntry + nil, // 214: openshell.v1.PolicyRevisionPayload.ProvenanceEntry + nil, // 215: openshell.v1.StoredPolicyRevision.ProvenanceEntry + nil, // 216: openshell.v1.CreateWorkspaceRequest.LabelsEntry + (*datamodelv1.ObjectMeta)(nil), // 217: openshell.datamodel.v1.ObjectMeta + (*sandboxv1.SandboxPolicy)(nil), // 218: openshell.sandbox.v1.SandboxPolicy + (*structpb.Struct)(nil), // 219: google.protobuf.Struct + (*datamodelv1.Provider)(nil), // 220: openshell.datamodel.v1.Provider + (*sandboxv1.NetworkEndpoint)(nil), // 221: openshell.sandbox.v1.NetworkEndpoint + (*sandboxv1.NetworkBinary)(nil), // 222: openshell.sandbox.v1.NetworkBinary + (*sandboxv1.SettingValue)(nil), // 223: openshell.sandbox.v1.SettingValue + (*sandboxv1.NetworkPolicyRule)(nil), // 224: openshell.sandbox.v1.NetworkPolicyRule + (*sandboxv1.L7DenyRule)(nil), // 225: openshell.sandbox.v1.L7DenyRule + (*sandboxv1.L7Rule)(nil), // 226: openshell.sandbox.v1.L7Rule + (*datamodelv1.Workspace)(nil), // 227: openshell.datamodel.v1.Workspace + (*datamodelv1.CredentialHandle)(nil), // 228: openshell.datamodel.v1.CredentialHandle + (*sandboxv1.GetSandboxConfigRequest)(nil), // 229: openshell.sandbox.v1.GetSandboxConfigRequest + (*sandboxv1.GetGatewayConfigRequest)(nil), // 230: openshell.sandbox.v1.GetGatewayConfigRequest + (*sandboxv1.GetSandboxConfigResponse)(nil), // 231: openshell.sandbox.v1.GetSandboxConfigResponse + (*sandboxv1.GetGatewayConfigResponse)(nil), // 232: openshell.sandbox.v1.GetGatewayConfigResponse } var file_openshell_proto_depIdxs = []int32{ 190, // 0: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential @@ -14525,19 +14563,19 @@ var file_openshell_proto_depIdxs = []int32{ 4, // 2: openshell.v1.GetGatewayInfoResponse.status:type_name -> openshell.v1.ServiceStatus 16, // 3: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo 17, // 4: openshell.v1.ComputeDriverInfo.capabilities:type_name -> openshell.v1.ComputeDriverCapabilities - 215, // 5: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 217, // 5: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 19, // 6: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec 23, // 7: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus 191, // 8: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry 22, // 9: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate - 216, // 10: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 218, // 10: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy 20, // 11: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements 21, // 12: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements 192, // 13: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry 193, // 14: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry 194, // 15: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry - 217, // 16: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct - 217, // 17: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct + 219, // 16: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct + 219, // 17: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct 24, // 18: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition 0, // 19: openshell.v1.SandboxStatus.phase:type_name -> openshell.v1.SandboxPhase 195, // 20: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry @@ -14546,11 +14584,11 @@ var file_openshell_proto_depIdxs = []int32{ 197, // 23: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry 18, // 24: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox 18, // 25: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox - 218, // 26: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 220, // 26: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider 18, // 27: openshell.v1.AttachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox 18, // 28: openshell.v1.DetachSandboxProviderResponse.sandbox:type_name -> openshell.v1.Sandbox 50, // 29: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse - 215, // 30: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 217, // 30: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 49, // 31: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint 198, // 32: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry 54, // 33: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout @@ -14561,18 +14599,18 @@ var file_openshell_proto_depIdxs = []int32{ 58, // 38: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit 53, // 39: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest 61, // 40: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize - 215, // 41: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 217, // 41: openshell.v1.SshSession.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 18, // 42: openshell.v1.SandboxStreamEvent.sandbox:type_name -> openshell.v1.Sandbox 65, // 43: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine 25, // 44: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent 66, // 45: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning 151, // 46: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate 199, // 47: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry - 218, // 48: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 218, // 49: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 220, // 48: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider + 220, // 49: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider 200, // 50: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry - 218, // 51: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider - 218, // 52: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider + 220, // 51: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider + 220, // 52: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider 95, // 53: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile 78, // 54: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride 83, // 55: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh @@ -14581,233 +14619,237 @@ var file_openshell_proto_depIdxs = []int32{ 81, // 58: openshell.v1.ProviderCredentialRefresh.material:type_name -> openshell.v1.ProviderCredentialRefreshMaterial 82, // 59: openshell.v1.ProviderCredentialRefresh.additional_outputs:type_name -> openshell.v1.ProviderCredentialRefreshOutput 1, // 60: openshell.v1.ProviderCredentialRefreshStatus.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 215, // 61: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 217, // 61: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 1, // 62: openshell.v1.StoredProviderCredentialRefreshState.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy 201, // 63: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry 202, // 64: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - 84, // 65: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 1, // 66: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 203, // 67: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - 84, // 68: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 84, // 69: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 2, // 70: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory - 80, // 71: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential - 219, // 72: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint - 220, // 73: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 85, // 74: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery - 204, // 75: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry - 215, // 76: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 95, // 77: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile - 95, // 78: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile - 95, // 79: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 76, // 80: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 77, // 81: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 95, // 82: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 76, // 83: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem - 77, // 84: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 95, // 85: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile - 76, // 86: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 77, // 87: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 109, // 88: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding - 205, // 89: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - 206, // 90: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - 207, // 91: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - 208, // 92: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - 216, // 93: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 221, // 94: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue - 113, // 95: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation - 209, // 96: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry - 114, // 97: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule - 115, // 98: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint - 116, // 99: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule - 117, // 100: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules - 118, // 101: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules - 119, // 102: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary - 222, // 103: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 223, // 104: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule - 224, // 105: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule - 210, // 106: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry - 127, // 107: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision - 127, // 108: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision - 3, // 109: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus - 3, // 110: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus - 216, // 111: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 211, // 112: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry - 65, // 113: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine - 65, // 114: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine - 134, // 115: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello - 137, // 116: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat - 144, // 117: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult - 145, // 118: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose - 135, // 119: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted - 136, // 120: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected - 138, // 121: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat - 139, // 122: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen - 145, // 123: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose - 140, // 124: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget - 141, // 125: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget - 142, // 126: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit - 146, // 127: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample - 148, // 128: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount - 222, // 129: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 147, // 130: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary - 150, // 131: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk - 149, // 132: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary - 150, // 133: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk - 222, // 134: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 169, // 135: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry - 216, // 136: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 212, // 137: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry - 222, // 138: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 213, // 139: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry - 214, // 140: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry - 225, // 141: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 225, // 142: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 225, // 143: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace - 215, // 144: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 5, // 145: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole - 5, // 146: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole - 183, // 147: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember - 183, // 148: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember - 80, // 149: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential - 110, // 150: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding - 10, // 151: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest - 12, // 152: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest - 14, // 153: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest - 26, // 154: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest - 27, // 155: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest - 28, // 156: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest - 29, // 157: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest - 30, // 158: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest - 31, // 159: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest - 32, // 160: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest - 33, // 161: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest - 34, // 162: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest - 41, // 163: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest - 43, // 164: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest - 44, // 165: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest - 45, // 166: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest - 47, // 167: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest - 51, // 168: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest - 53, // 169: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest - 59, // 170: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame - 60, // 171: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput - 67, // 172: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest - 68, // 173: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest - 69, // 174: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest - 74, // 175: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest - 75, // 176: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest - 99, // 177: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest - 101, // 178: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest - 103, // 179: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest - 70, // 180: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest - 87, // 181: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest - 89, // 182: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest - 91, // 183: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest - 93, // 184: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest - 71, // 185: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest - 106, // 186: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest - 226, // 187: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest - 227, // 188: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest - 112, // 189: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest - 121, // 190: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest - 123, // 191: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest - 125, // 192: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest - 108, // 193: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest - 128, // 194: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest - 129, // 195: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest - 132, // 196: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage - 143, // 197: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame - 63, // 198: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest - 152, // 199: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest - 154, // 200: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest - 156, // 201: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest - 158, // 202: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest - 160, // 203: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest - 162, // 204: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest - 164, // 205: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest - 166, // 206: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest - 168, // 207: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest - 6, // 208: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest - 8, // 209: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest - 175, // 210: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest - 177, // 211: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest - 179, // 212: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest - 181, // 213: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest - 184, // 214: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest - 186, // 215: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest - 188, // 216: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest - 11, // 217: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse - 13, // 218: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse - 15, // 219: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse - 35, // 220: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse - 35, // 221: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse - 36, // 222: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse - 37, // 223: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse - 38, // 224: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse - 39, // 225: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse - 40, // 226: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse - 35, // 227: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse - 35, // 228: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse - 42, // 229: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse - 50, // 230: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse - 50, // 231: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse - 46, // 232: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse - 48, // 233: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse - 52, // 234: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse - 57, // 235: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent - 59, // 236: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame - 57, // 237: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent - 72, // 238: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse - 72, // 239: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse - 73, // 240: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse - 98, // 241: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse - 97, // 242: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse - 100, // 243: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse - 102, // 244: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse - 104, // 245: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse - 72, // 246: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse - 88, // 247: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse - 90, // 248: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse - 92, // 249: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse - 94, // 250: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse - 105, // 251: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse - 107, // 252: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse - 228, // 253: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse - 229, // 254: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse - 120, // 255: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse - 122, // 256: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse - 124, // 257: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse - 126, // 258: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse - 111, // 259: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse - 131, // 260: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse - 130, // 261: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse - 133, // 262: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage - 143, // 263: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame - 64, // 264: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent - 153, // 265: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse - 155, // 266: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse - 157, // 267: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse - 159, // 268: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse - 161, // 269: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse - 163, // 270: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse - 165, // 271: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse - 167, // 272: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse - 170, // 273: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse - 7, // 274: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse - 9, // 275: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse - 176, // 276: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse - 178, // 277: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse - 180, // 278: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse - 182, // 279: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse - 185, // 280: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse - 187, // 281: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse - 189, // 282: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse - 217, // [217:283] is the sub-list for method output_type - 151, // [151:217] is the sub-list for method input_type - 151, // [151:151] is the sub-list for extension type_name - 151, // [151:151] is the sub-list for extension extendee - 0, // [0:151] is the sub-list for field type_name + 203, // 65: openshell.v1.StoredProviderCredentialRefreshState.secret_material_handles:type_name -> openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry + 204, // 66: openshell.v1.StoredProviderCredentialRefreshState.pending_secret_deletions:type_name -> openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntry + 84, // 67: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 1, // 68: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy + 205, // 69: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + 84, // 70: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 84, // 71: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 2, // 72: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory + 80, // 73: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential + 221, // 74: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint + 222, // 75: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 85, // 76: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery + 206, // 77: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry + 217, // 78: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 95, // 79: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile + 95, // 80: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile + 95, // 81: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 76, // 82: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 83: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 95, // 84: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 76, // 85: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 86: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 95, // 87: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile + 76, // 88: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 89: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 109, // 90: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding + 207, // 91: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + 208, // 92: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + 209, // 93: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + 210, // 94: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + 218, // 95: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 223, // 96: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue + 113, // 97: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation + 211, // 98: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry + 114, // 99: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule + 115, // 100: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint + 116, // 101: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule + 117, // 102: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules + 118, // 103: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules + 119, // 104: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary + 224, // 105: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 225, // 106: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule + 226, // 107: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule + 212, // 108: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry + 127, // 109: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision + 127, // 110: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision + 3, // 111: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus + 3, // 112: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus + 218, // 113: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 213, // 114: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry + 65, // 115: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine + 65, // 116: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine + 134, // 117: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello + 137, // 118: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat + 144, // 119: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult + 145, // 120: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose + 135, // 121: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted + 136, // 122: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected + 138, // 123: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat + 139, // 124: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen + 145, // 125: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose + 140, // 126: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget + 141, // 127: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget + 142, // 128: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit + 146, // 129: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample + 148, // 130: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount + 224, // 131: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 147, // 132: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary + 150, // 133: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk + 149, // 134: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary + 150, // 135: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk + 224, // 136: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 169, // 137: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry + 218, // 138: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 214, // 139: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry + 224, // 140: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 215, // 141: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry + 216, // 142: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry + 227, // 143: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 227, // 144: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 227, // 145: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace + 217, // 146: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 5, // 147: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole + 5, // 148: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole + 183, // 149: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember + 183, // 150: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember + 228, // 151: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle + 228, // 152: openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle + 80, // 153: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential + 110, // 154: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding + 10, // 155: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest + 12, // 156: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest + 14, // 157: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest + 26, // 158: openshell.v1.OpenShell.CreateSandbox:input_type -> openshell.v1.CreateSandboxRequest + 27, // 159: openshell.v1.OpenShell.GetSandbox:input_type -> openshell.v1.GetSandboxRequest + 28, // 160: openshell.v1.OpenShell.ListSandboxes:input_type -> openshell.v1.ListSandboxesRequest + 29, // 161: openshell.v1.OpenShell.ListSandboxProviders:input_type -> openshell.v1.ListSandboxProvidersRequest + 30, // 162: openshell.v1.OpenShell.AttachSandboxProvider:input_type -> openshell.v1.AttachSandboxProviderRequest + 31, // 163: openshell.v1.OpenShell.DetachSandboxProvider:input_type -> openshell.v1.DetachSandboxProviderRequest + 32, // 164: openshell.v1.OpenShell.DeleteSandbox:input_type -> openshell.v1.DeleteSandboxRequest + 33, // 165: openshell.v1.OpenShell.StopSandbox:input_type -> openshell.v1.StopSandboxRequest + 34, // 166: openshell.v1.OpenShell.StartSandbox:input_type -> openshell.v1.StartSandboxRequest + 41, // 167: openshell.v1.OpenShell.CreateSshSession:input_type -> openshell.v1.CreateSshSessionRequest + 43, // 168: openshell.v1.OpenShell.ExposeService:input_type -> openshell.v1.ExposeServiceRequest + 44, // 169: openshell.v1.OpenShell.GetService:input_type -> openshell.v1.GetServiceRequest + 45, // 170: openshell.v1.OpenShell.ListServices:input_type -> openshell.v1.ListServicesRequest + 47, // 171: openshell.v1.OpenShell.DeleteService:input_type -> openshell.v1.DeleteServiceRequest + 51, // 172: openshell.v1.OpenShell.RevokeSshSession:input_type -> openshell.v1.RevokeSshSessionRequest + 53, // 173: openshell.v1.OpenShell.ExecSandbox:input_type -> openshell.v1.ExecSandboxRequest + 59, // 174: openshell.v1.OpenShell.ForwardTcp:input_type -> openshell.v1.TcpForwardFrame + 60, // 175: openshell.v1.OpenShell.ExecSandboxInteractive:input_type -> openshell.v1.ExecSandboxInput + 67, // 176: openshell.v1.OpenShell.CreateProvider:input_type -> openshell.v1.CreateProviderRequest + 68, // 177: openshell.v1.OpenShell.GetProvider:input_type -> openshell.v1.GetProviderRequest + 69, // 178: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest + 74, // 179: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest + 75, // 180: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest + 99, // 181: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest + 101, // 182: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest + 103, // 183: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest + 70, // 184: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest + 87, // 185: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest + 89, // 186: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest + 91, // 187: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest + 93, // 188: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest + 71, // 189: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest + 106, // 190: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest + 229, // 191: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest + 230, // 192: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest + 112, // 193: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest + 121, // 194: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest + 123, // 195: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest + 125, // 196: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest + 108, // 197: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest + 128, // 198: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest + 129, // 199: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest + 132, // 200: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage + 143, // 201: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame + 63, // 202: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest + 152, // 203: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest + 154, // 204: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest + 156, // 205: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest + 158, // 206: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest + 160, // 207: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest + 162, // 208: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest + 164, // 209: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest + 166, // 210: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest + 168, // 211: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest + 6, // 212: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest + 8, // 213: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest + 175, // 214: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest + 177, // 215: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest + 179, // 216: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest + 181, // 217: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest + 184, // 218: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest + 186, // 219: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest + 188, // 220: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest + 11, // 221: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse + 13, // 222: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse + 15, // 223: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse + 35, // 224: openshell.v1.OpenShell.CreateSandbox:output_type -> openshell.v1.SandboxResponse + 35, // 225: openshell.v1.OpenShell.GetSandbox:output_type -> openshell.v1.SandboxResponse + 36, // 226: openshell.v1.OpenShell.ListSandboxes:output_type -> openshell.v1.ListSandboxesResponse + 37, // 227: openshell.v1.OpenShell.ListSandboxProviders:output_type -> openshell.v1.ListSandboxProvidersResponse + 38, // 228: openshell.v1.OpenShell.AttachSandboxProvider:output_type -> openshell.v1.AttachSandboxProviderResponse + 39, // 229: openshell.v1.OpenShell.DetachSandboxProvider:output_type -> openshell.v1.DetachSandboxProviderResponse + 40, // 230: openshell.v1.OpenShell.DeleteSandbox:output_type -> openshell.v1.DeleteSandboxResponse + 35, // 231: openshell.v1.OpenShell.StopSandbox:output_type -> openshell.v1.SandboxResponse + 35, // 232: openshell.v1.OpenShell.StartSandbox:output_type -> openshell.v1.SandboxResponse + 42, // 233: openshell.v1.OpenShell.CreateSshSession:output_type -> openshell.v1.CreateSshSessionResponse + 50, // 234: openshell.v1.OpenShell.ExposeService:output_type -> openshell.v1.ServiceEndpointResponse + 50, // 235: openshell.v1.OpenShell.GetService:output_type -> openshell.v1.ServiceEndpointResponse + 46, // 236: openshell.v1.OpenShell.ListServices:output_type -> openshell.v1.ListServicesResponse + 48, // 237: openshell.v1.OpenShell.DeleteService:output_type -> openshell.v1.DeleteServiceResponse + 52, // 238: openshell.v1.OpenShell.RevokeSshSession:output_type -> openshell.v1.RevokeSshSessionResponse + 57, // 239: openshell.v1.OpenShell.ExecSandbox:output_type -> openshell.v1.ExecSandboxEvent + 59, // 240: openshell.v1.OpenShell.ForwardTcp:output_type -> openshell.v1.TcpForwardFrame + 57, // 241: openshell.v1.OpenShell.ExecSandboxInteractive:output_type -> openshell.v1.ExecSandboxEvent + 72, // 242: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse + 72, // 243: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse + 73, // 244: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse + 98, // 245: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse + 97, // 246: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse + 100, // 247: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse + 102, // 248: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse + 104, // 249: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse + 72, // 250: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse + 88, // 251: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse + 90, // 252: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse + 92, // 253: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse + 94, // 254: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse + 105, // 255: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse + 107, // 256: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse + 231, // 257: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse + 232, // 258: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse + 120, // 259: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse + 122, // 260: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse + 124, // 261: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse + 126, // 262: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse + 111, // 263: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse + 131, // 264: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse + 130, // 265: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse + 133, // 266: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage + 143, // 267: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame + 64, // 268: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent + 153, // 269: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse + 155, // 270: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse + 157, // 271: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse + 159, // 272: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse + 161, // 273: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse + 163, // 274: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse + 165, // 275: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse + 167, // 276: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse + 170, // 277: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse + 7, // 278: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse + 9, // 279: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse + 176, // 280: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse + 178, // 281: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse + 180, // 282: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse + 182, // 283: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse + 185, // 284: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse + 187, // 285: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse + 189, // 286: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse + 221, // [221:287] is the sub-list for method output_type + 155, // [155:221] is the sub-list for method input_type + 155, // [155:155] is the sub-list for extension type_name + 155, // [155:155] is the sub-list for extension extendee + 0, // [0:155] is the sub-list for field type_name } func init() { file_openshell_proto_init() } @@ -14880,7 +14922,7 @@ func file_openshell_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_openshell_proto_rawDesc), len(file_openshell_proto_rawDesc)), NumEnums: 6, - NumMessages: 209, + NumMessages: 211, NumExtensions: 0, NumServices: 1, }, From c32e6274ad6463bda3a41eace0c1e277a3d2ca4a Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Tue, 18 Aug 2026 18:03:06 -0700 Subject: [PATCH 2/5] fix(providers): harden refresh credential lifecycle Signed-off-by: Mrunal Patel --- crates/openshell-server/src/credentials.rs | 148 +- crates/openshell-server/src/grpc/provider.rs | 217 ++- .../openshell-server/src/provider_refresh.rs | 834 ++++++++--- docs/sandboxes/providers-v2.mdx | 4 + proto/openshell.proto | 15 +- sdk/go/proto/openshellv1/openshell.pb.go | 1318 +++++++++-------- 6 files changed, 1642 insertions(+), 894 deletions(-) diff --git a/crates/openshell-server/src/credentials.rs b/crates/openshell-server/src/credentials.rs index 396be9de22..12d2835be3 100644 --- a/crates/openshell-server/src/credentials.rs +++ b/crates/openshell-server/src/credentials.rs @@ -30,7 +30,7 @@ use openshell_core::proto::credentials::v1::{ GetCredentialDriverCapabilitiesResponse, ResolveCredentialRequest, ResolveCredentialsRequest, ResolvedCredential, StoreCredentialRequest, credential_driver_client::CredentialDriverClient, }; -use openshell_core::proto::{CredentialHandle, Provider}; +use openshell_core::proto::{CredentialHandle, Provider, StoredRefreshMaterialDeletion}; use openshell_core::{Config, Error, Result as CoreResult}; use openshell_driver_db_credstore::{ CredentialObjectWrite, DbCredstoreCredentialDriver, DbCredstoreObjectStore, @@ -84,6 +84,22 @@ pub trait CredentialDriver: std::fmt::Debug + Send + Sync { fn stored_credential_count(&self) -> Option { None } + + #[cfg(test)] + fn fail_next_store(&self) {} + + #[cfg(test)] + fn fail_next_delete(&self) {} + + #[cfg(test)] + fn gate_next_store( + &self, + ) -> Option<( + tokio::sync::oneshot::Receiver<()>, + tokio::sync::oneshot::Sender<()>, + )> { + None + } } #[derive(Debug, Clone, Default, PartialEq, Eq)] @@ -224,6 +240,33 @@ impl CredentialRuntime { .and_then(|driver| driver.stored_credential_count()) } + #[cfg(test)] + pub(crate) fn fail_next_store(&self) { + if let Some(driver) = self.drivers.get(&self.registry.storage_owner_name()) { + driver.fail_next_store(); + } + } + + #[cfg(test)] + pub(crate) fn fail_next_delete(&self) { + if let Some(driver) = self.drivers.get(&self.registry.storage_owner_name()) { + driver.fail_next_delete(); + } + } + + #[cfg(test)] + pub(crate) fn gate_next_store( + &self, + ) -> ( + tokio::sync::oneshot::Receiver<()>, + tokio::sync::oneshot::Sender<()>, + ) { + self.drivers + .get(&self.registry.storage_owner_name()) + .and_then(|driver| driver.gate_next_store()) + .expect("test credential driver supports store gating") + } + pub async fn store_provider_credentials( &self, provider_name: &str, @@ -406,6 +449,10 @@ impl CredentialRuntime { material_by_storage_key.insert(storage_key.clone(), material_key.clone()); storage_handles.insert(storage_key, handle.clone()); } + // Reuse the normal driver-batched resolver with a synthetic provider. + // Refresh inputs are gateway-only and have no provider-level expiry; + // passing zero below prevents an expired injectable credential from + // suppressing resolution of an otherwise valid refresh-material handle. let provider = Provider { metadata: Some(openshell_core::proto::datamodel::v1::ObjectMeta { id: scope.provider_id.to_string(), @@ -456,6 +503,48 @@ impl CredentialRuntime { .await } + pub async fn delete_refresh_material_deletions( + &self, + scope: RefreshMaterialScope<'_>, + deletions: &[StoredRefreshMaterialDeletion], + ) -> Result<(), Status> { + let futures = deletions.iter().map(|deletion| async move { + if deletion.material_key.is_empty() { + return Err(Status::failed_precondition( + "pending refresh-material deletion has no material key", + )); + } + let handle = deletion.handle.clone().ok_or_else(|| { + Status::failed_precondition( + "pending refresh-material deletion has no credential handle", + ) + })?; + let storage_key = + refresh_material_storage_key(scope.credential_key, &deletion.material_key); + self.delete_provider_credential_handle( + scope.provider_name, + scope.workspace, + scope.provider_id, + &storage_key, + handle, + ) + .await + }); + let results = futures::future::join_all(futures).await; + let mut first_error = None; + for result in results { + if let Err(err) = result + && first_error.is_none() + { + first_error = Some(err); + } + } + if let Some(err) = first_error { + return Err(err); + } + Ok(()) + } + pub async fn delete_provider_credential_handles( &self, provider_name: &str, @@ -1618,6 +1707,15 @@ async fn connect_credential_driver_socket( #[derive(Debug)] struct TestStaticCredentialDriver { values: std::sync::Mutex>, + fail_next_store: std::sync::atomic::AtomicBool, + fail_next_delete: std::sync::atomic::AtomicBool, + #[cfg(test)] + store_gate: std::sync::Mutex< + Option<( + tokio::sync::oneshot::Sender<()>, + tokio::sync::oneshot::Receiver<()>, + )>, + >, } #[cfg(any(test, feature = "test-support"))] @@ -1627,6 +1725,10 @@ impl TestStaticCredentialDriver { fn new() -> Self { Self { values: std::sync::Mutex::new(HashMap::new()), + fail_next_store: std::sync::atomic::AtomicBool::new(false), + fail_next_delete: std::sync::atomic::AtomicBool::new(false), + #[cfg(test)] + store_gate: std::sync::Mutex::new(None), } } @@ -1649,6 +1751,19 @@ impl CredentialDriver for TestStaticCredentialDriver { &self, request: StoreCredentialRequest, ) -> Result { + #[cfg(test)] + let gate = self.store_gate.lock().ok().and_then(|mut gate| gate.take()); + #[cfg(test)] + if let Some((hit, release)) = gate { + let _ = hit.send(()); + let _ = release.await; + } + if self + .fail_next_store + .swap(false, std::sync::atomic::Ordering::SeqCst) + { + return Err(Status::unavailable("injected credential store failure")); + } let handle = request .existing_handle .map(|handle| handle.handle) @@ -1671,6 +1786,12 @@ impl CredentialDriver for TestStaticCredentialDriver { } async fn delete_credential(&self, request: DeleteCredentialRequest) -> Result<(), Status> { + if self + .fail_next_delete + .swap(false, std::sync::atomic::Ordering::SeqCst) + { + return Err(Status::unavailable("injected credential delete failure")); + } let handle = Self::handle_from_request("delete", request.handle)?; self.values .lock() @@ -1707,6 +1828,31 @@ impl CredentialDriver for TestStaticCredentialDriver { fn stored_credential_count(&self) -> Option { self.values.lock().ok().map(|values| values.len()) } + + #[cfg(test)] + fn fail_next_store(&self) { + self.fail_next_store + .store(true, std::sync::atomic::Ordering::SeqCst); + } + + #[cfg(test)] + fn fail_next_delete(&self) { + self.fail_next_delete + .store(true, std::sync::atomic::Ordering::SeqCst); + } + + #[cfg(test)] + fn gate_next_store( + &self, + ) -> Option<( + tokio::sync::oneshot::Receiver<()>, + tokio::sync::oneshot::Sender<()>, + )> { + let (hit_tx, hit_rx) = tokio::sync::oneshot::channel(); + let (release_tx, release_rx) = tokio::sync::oneshot::channel(); + *self.store_gate.lock().ok()? = Some((hit_tx, release_rx)); + Some((hit_rx, release_tx)) + } } #[cfg(test)] diff --git a/crates/openshell-server/src/grpc/provider.rs b/crates/openshell-server/src/grpc/provider.rs index 2f2c67949f..6ee17b632c 100644 --- a/crates/openshell-server/src/grpc/provider.rs +++ b/crates/openshell-server/src/grpc/provider.rs @@ -5,6 +5,7 @@ #![allow(clippy::result_large_err)] // gRPC handlers return Result, Status> +#[cfg(test)] use crate::credentials::RefreshMaterialScope; use crate::persistence::{ ObjectId, ObjectLabels, ObjectName, ObjectType, Store, WriteCondition, generate_name, @@ -529,33 +530,11 @@ pub(super) async fn delete_provider_record( workspace: &str, name: &str, ) -> Result { - if name.is_empty() { - return Err(Status::invalid_argument("name is required")); - } - - let Some(provider) = store - .get_message_by_name::(workspace, name) - .await - .map_err(|e| Status::internal(format!("fetch provider failed: {e}")))? - else { - return Ok(false); - }; - - let blocking_sandboxes = sandboxes_using_provider(store, workspace, name).await?; - if !blocking_sandboxes.is_empty() { - return Err(Status::failed_precondition(format!( - "provider '{name}' is attached to sandbox(es): {}", - blocking_sandboxes.join(", ") - ))); - } - - crate::provider_refresh::delete_refresh_states_for_provider(store, provider.object_id()) - .await?; - - store - .delete_by_name(Provider::object_type(), workspace, name) - .await - .map_err(|e| Status::internal(format!("delete provider failed: {e}"))) + let credentials = crate::credentials::CredentialRuntime::from_config( + &openshell_core::Config::new(None).with_credential_drivers(["test-static"]), + ) + .map_err(|err| Status::internal(format!("create test credential runtime failed: {err}")))?; + delete_provider_record_with_credentials(store, workspace, &credentials, name).await } pub(super) async fn delete_provider_record_with_credentials( @@ -3754,7 +3733,7 @@ pub(super) async fn handle_configure_provider_refresh( "max_lifetime_seconds material must be greater than or equal to 0", )); } - let mut existing_refresh_state = crate::provider_refresh::get_refresh_state( + let existing_refresh_state = crate::provider_refresh::get_refresh_state( state.store.as_ref(), &workspace, provider.object_id(), @@ -3777,23 +3756,6 @@ pub(super) async fn handle_configure_provider_refresh( .as_ref() .map(|metadata| metadata.resource_version) }); - if let Some(existing) = existing_refresh_state.as_mut() - && !existing.pending_secret_deletions.is_empty() - { - state - .credentials - .delete_refresh_material_handles( - RefreshMaterialScope { - provider_name: &existing.provider_name, - workspace: existing.object_workspace(), - provider_id: &existing.provider_id, - credential_key: &existing.credential_key, - }, - &existing.pending_secret_deletions, - ) - .await?; - existing.pending_secret_deletions.clear(); - } let expires_at_ms = request.expires_at_ms.unwrap_or_else(|| { existing_refresh_state .as_ref() @@ -3809,25 +3771,6 @@ pub(super) async fn handle_configure_provider_refresh( .map(|value| (key.clone(), value)) }) .collect(); - let material_staging_id = format!( - "{}-refresh-config-{}", - provider.object_id(), - uuid::Uuid::new_v4() - ); - let staged_material_handles = state - .credentials - .store_refresh_material_with_object_id( - RefreshMaterialScope { - provider_name: provider.object_name(), - workspace: &workspace, - provider_id: provider.object_id(), - credential_key, - }, - &material_staging_id, - &secret_material, - &HashMap::new(), - ) - .await?; let mut state_record = crate::provider_refresh::new_refresh_state( &provider, &workspace, @@ -3844,17 +3787,35 @@ pub(super) async fn handle_configure_provider_refresh( additional_output_keys, }, )?; - state_record.secret_material_handles = staged_material_handles.clone(); - if let Some(existing) = existing_refresh_state { - state_record.metadata = existing.metadata; + if let Some(existing) = existing_refresh_state.as_ref() { + state_record.metadata.clone_from(&existing.metadata); state_record.last_refresh_at_ms = existing.last_refresh_at_ms; state_record .pending_secret_deletions - .extend(existing.pending_secret_deletions); - state_record - .pending_secret_deletions - .extend(existing.secret_material_handles); + .extend(existing.pending_secret_deletions.clone()); + for (material_key, handle) in &existing.secret_material_handles { + crate::provider_refresh::enqueue_pending_secret_deletion( + &mut state_record, + material_key, + handle.clone(), + ); + } } + let material_staging_id = format!( + "{}-refresh-config-{}", + provider.object_id(), + uuid::Uuid::new_v4() + ); + let staged_material_handles = state + .credentials + .store_refresh_material_with_object_id( + crate::provider_refresh::refresh_material_scope(&state_record), + &material_staging_id, + &secret_material, + &HashMap::new(), + ) + .await?; + state_record.secret_material_handles = staged_material_handles.clone(); let persist_result = if let Some(expected_version) = existing_refresh_version { match crate::provider_refresh::replace_refresh_state_if_current( state.store.as_ref(), @@ -3876,12 +3837,7 @@ pub(super) async fn handle_configure_provider_refresh( if let Err(cleanup_err) = state .credentials .delete_refresh_material_handles( - RefreshMaterialScope { - provider_name: provider.object_name(), - workspace: &workspace, - provider_id: provider.object_id(), - credential_key, - }, + crate::provider_refresh::refresh_material_scope(&state_record), &staged_material_handles, ) .await @@ -3954,7 +3910,7 @@ pub(super) async fn handle_rotate_provider_credential( let refresh_state = crate::provider_refresh::refresh_provider_credential( state.store.as_ref(), &workspace, - Some(&state.credentials), + &state.credentials, Some(&state.compute), provider_name, credential_key, @@ -5980,6 +5936,111 @@ mod tests { ); } + #[tokio::test] + async fn configure_provider_refresh_conflict_cleans_only_staged_material() { + let state = test_server_state().await; + import_test_graph_refresh_profile(&state).await; + create_provider_record( + state.store.as_ref(), + "default", + Provider { + metadata: Some(openshell_core::proto::datamodel::v1::ObjectMeta { + name: "configure-conflict".to_string(), + workspace: "default".to_string(), + ..Default::default() + }), + r#type: TEST_GRAPH_PROVIDER_TYPE.to_string(), + profile_workspace: "default".to_string(), + ..Default::default() + }, + ) + .await + .unwrap(); + let request = |client_secret: &str| ConfigureProviderRefreshRequest { + provider: "configure-conflict".to_string(), + credential_key: "MS_GRAPH_ACCESS_TOKEN".to_string(), + strategy: ProviderCredentialRefreshStrategy::Oauth2ClientCredentials as i32, + material: HashMap::from([ + ("tenant_id".to_string(), "tenant".to_string()), + ("client_id".to_string(), "client-id".to_string()), + ("client_secret".to_string(), client_secret.to_string()), + ]), + secret_material_keys: vec!["client_secret".to_string()], + expires_at_ms: None, + workspace: "default".to_string(), + }; + handle_configure_provider_refresh(&state, authed_request(request("original-secret"))) + .await + .unwrap(); + let provider = state + .store + .get_message_by_name::("default", "configure-conflict") + .await + .unwrap() + .unwrap(); + let original = crate::provider_refresh::get_refresh_state( + state.store.as_ref(), + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert_eq!(state.credentials.stored_credential_count(), Some(1)); + let (store_hit, release_store) = state.credentials.gate_next_store(); + + let configure = handle_configure_provider_refresh( + &state, + authed_request(request("replacement-secret")), + ); + let supersede = async { + store_hit.await.unwrap(); + let mut winner = crate::provider_refresh::get_refresh_state( + state.store.as_ref(), + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + winner.last_error = "won-by-concurrent-writer".to_string(); + crate::provider_refresh::put_refresh_state(state.store.as_ref(), &winner) + .await + .unwrap(); + release_store.send(()).unwrap(); + }; + let (result, ()) = tokio::join!(configure, supersede); + + assert_eq!(result.unwrap_err().code(), Code::Aborted); + assert_eq!(state.credentials.stored_credential_count(), Some(1)); + let stored = crate::provider_refresh::get_refresh_state( + state.store.as_ref(), + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert_eq!(stored.authorization_epoch, original.authorization_epoch); + assert_eq!(stored.last_error, "won-by-concurrent-writer"); + assert!(stored.pending_secret_deletions.is_empty()); + assert_eq!( + state + .credentials + .resolve_refresh_material( + crate::provider_refresh::refresh_material_scope(&stored), + &stored.secret_material_handles, + ) + .await + .unwrap() + .get("client_secret"), + Some(&"original-secret".to_string()) + ); + } + async fn state_with_authoritative_profiles_over_default_grants() -> Arc { let state = test_server_state().await; let store = state.store.as_ref(); diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index 1f896528e0..e91e4c2e1d 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -10,7 +10,7 @@ use crate::persistence::{ObjectType, PersistenceError, Store, WriteCondition, cu use openshell_core::ObjectWorkspace; use openshell_core::proto::{ CredentialHandle, Provider, ProviderCredentialRefreshStatus, ProviderCredentialRefreshStrategy, - StoredProviderCredentialRefreshState, + StoredProviderCredentialRefreshState, StoredRefreshMaterialDeletion, }; use openshell_core::{ObjectId, ObjectName, SetResourceVersion}; use prost::Message; @@ -25,7 +25,7 @@ const DEFAULT_MAX_LIFETIME_SECONDS: i64 = 3600; const REFRESH_ERROR_RETRY_SECONDS: i64 = 60; const REFRESH_WORKER_PAGE_SIZE: u32 = 1000; -fn refresh_material_scope( +pub fn refresh_material_scope( state: &StoredProviderCredentialRefreshState, ) -> RefreshMaterialScope<'_> { RefreshMaterialScope { @@ -195,24 +195,6 @@ pub async fn get_refresh_state( .map_err(|e| Status::internal(format!("fetch provider refresh state failed: {e}"))) } -#[cfg(test)] -pub async fn delete_refresh_state( - store: &Store, - workspace: &str, - provider_id: &str, - credential_key: &str, -) -> Result { - let name = refresh_state_name(provider_id, credential_key); - store - .delete_by_name( - StoredProviderCredentialRefreshState::object_type(), - workspace, - &name, - ) - .await - .map_err(|e| Status::internal(format!("delete provider refresh state failed: {e}"))) -} - pub async fn delete_refresh_state_with_credentials( store: &Store, credentials: &crate::credentials::CredentialRuntime, @@ -249,12 +231,7 @@ pub async fn delete_refresh_state_with_credentials( } } - credentials - .delete_refresh_material_handles( - refresh_material_scope(&state), - &state.pending_secret_deletions, - ) - .await?; + delete_pending_secret_handles(credentials, &state).await?; credentials .delete_refresh_material_handles( refresh_material_scope(&state), @@ -276,29 +253,6 @@ pub async fn delete_refresh_state_with_credentials( }) } -#[cfg(test)] -pub async fn delete_refresh_states_for_provider( - store: &Store, - provider_id: &str, -) -> Result { - let states = list_refresh_states_for_provider(store, provider_id).await?; - let mut deleted = 0; - for state in &states { - if store - .delete_by_name( - StoredProviderCredentialRefreshState::object_type(), - state.object_workspace(), - state.object_name(), - ) - .await - .map_err(|e| Status::internal(format!("delete provider refresh state failed: {e}")))? - { - deleted += 1; - } - } - Ok(deleted) -} - pub async fn delete_refresh_states_for_provider_with_credentials( store: &Store, credentials: &crate::credentials::CredentialRuntime, @@ -398,7 +352,7 @@ pub fn new_refresh_state( additional_output_keys: config.additional_output_keys, authorization_epoch: uuid::Uuid::new_v4().to_string(), secret_material_handles: HashMap::new(), - pending_secret_deletions: HashMap::new(), + pending_secret_deletions: Vec::new(), }) } @@ -511,6 +465,31 @@ async fn resolve_refresh_material( Ok(transient) } +pub fn enqueue_pending_secret_deletion( + state: &mut StoredProviderCredentialRefreshState, + material_key: &str, + handle: CredentialHandle, +) { + state + .pending_secret_deletions + .push(StoredRefreshMaterialDeletion { + material_key: material_key.to_string(), + handle: Some(handle), + }); +} + +async fn delete_pending_secret_handles( + credentials: &crate::credentials::CredentialRuntime, + state: &StoredProviderCredentialRefreshState, +) -> Result<(), Status> { + credentials + .delete_refresh_material_deletions( + refresh_material_scope(state), + &state.pending_secret_deletions, + ) + .await +} + async fn cleanup_pending_secret_deletions( store: &Store, credentials: Option<&crate::credentials::CredentialRuntime>, @@ -525,24 +504,70 @@ async fn cleanup_pending_secret_deletions( "provider refresh cleanup requires the configured credential runtime", ) })?; - credentials - .delete_refresh_material_handles( - refresh_material_scope(state), - &state.pending_secret_deletions, - ) - .await?; - state.pending_secret_deletions.clear(); - let new_version = persist_refresh_state_if_current(store, state, expected_version) + delete_pending_secret_handles(credentials, state).await?; + // Keep the caller's in-memory state unchanged unless the CAS succeeds. A + // failed cleanup must not let the live refresh path persist a locally + // cleared tombstone list over the durable retry references. + let mut cleaned = state.clone(); + cleaned.pending_secret_deletions.clear(); + let new_version = persist_refresh_state_if_current(store, &cleaned, expected_version) .await? .ok_or_else(|| { Status::aborted("provider refresh was deleted or superseded during secret cleanup") })?; + if let Some(metadata) = cleaned.metadata.as_mut() { + metadata.resource_version = new_version; + } + *state = cleaned; + Ok(new_version) +} + +async fn persist_refresh_error_state( + store: &Store, + state: &mut StoredProviderCredentialRefreshState, + expected_version: u64, + error: &Status, +) -> Result { + let now_ms = current_time_ms(); + state.status = "error".to_string(); + state.last_error = error.message().to_string(); + state.next_refresh_at_ms = + now_ms.saturating_add(REFRESH_ERROR_RETRY_SECONDS.saturating_mul(1000)); + let new_version = persist_refresh_state_if_current(store, state, expected_version) + .await? + .ok_or_else(|| { + Status::aborted( + "provider refresh was deleted or superseded while recording a refresh error", + ) + })?; if let Some(metadata) = state.metadata.as_mut() { metadata.resource_version = new_version; } Ok(new_version) } +fn validate_secret_material_references( + state: &StoredProviderCredentialRefreshState, +) -> Result<(), Status> { + let mut missing: Vec<_> = state + .secret_material_keys + .iter() + .filter(|key| { + !state.material.contains_key(*key) && !state.secret_material_handles.contains_key(*key) + }) + .cloned() + .collect(); + if missing.is_empty() { + return Ok(()); + } + missing.sort(); + missing.dedup(); + Err(Status::failed_precondition(format!( + "provider refresh secret material is missing both inline values and credential handles for {}; a mixed-version gateway upgrade may have discarded the handles, so restore the refresh state or reconfigure the grant", + missing.join(", ") + ))) +} + async fn migrate_inline_secret_material( store: &Store, credentials: Option<&crate::credentials::CredentialRuntime>, @@ -625,7 +650,7 @@ async fn migrate_inline_secret_material( pub async fn refresh_provider_credential( store: &Store, workspace: &str, - credentials: Option<&crate::credentials::CredentialRuntime>, + credentials: &crate::credentials::CredentialRuntime, compute: Option<&crate::compute::ComputeRuntime>, provider_name: &str, credential_key: &str, @@ -649,7 +674,8 @@ pub async fn refresh_provider_credential( "provider refresh is being deleted", )); } - let mut state = migrate_inline_secret_material(store, credentials, &state).await?; + let mut state = migrate_inline_secret_material(store, Some(credentials), &state).await?; + validate_secret_material_references(&state)?; // Generation of the refresh at the start of the rotation. Terminal persists // match on it so a concurrent delete or rotation is detected rather than // clobbered, and a deleted refresh is never recreated (CWE-362). @@ -657,8 +683,25 @@ pub async fn refresh_provider_credential( .metadata .as_ref() .map_or(0, |meta| meta.resource_version); - let expected_version = - cleanup_pending_secret_deletions(store, credentials, &mut state, expected_version).await?; + let expected_version = match cleanup_pending_secret_deletions( + store, + Some(credentials), + &mut state, + expected_version, + ) + .await + { + Ok(new_version) => new_version, + Err(err) => { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + error = %err, + "provider refresh material cleanup failed; continuing with live refresh" + ); + expected_version + } + }; info!( provider = %state.provider_name, @@ -674,12 +717,7 @@ pub async fn refresh_provider_credential( // Otherwise disabling providers_v2_enabled leaves already-configured refresh // states that the worker and manual rotation keep minting from. if let Err(err) = ensure_refresh_providers_v2_gate(store, &state).await { - let now_ms = current_time_ms(); - state.status = "error".to_string(); - state.last_error = err.message().to_string(); - state.next_refresh_at_ms = - now_ms.saturating_add(REFRESH_ERROR_RETRY_SECONDS.saturating_mul(1000)); - persist_refresh_state_if_current(store, &state, expected_version).await?; + persist_refresh_error_state(store, &mut state, expected_version, &err).await?; warn!( provider = %state.provider_name, credential_key = %state.credential_key, @@ -691,7 +729,7 @@ pub async fn refresh_provider_credential( return Err(err); } - let mint_result = match resolve_refresh_material(credentials, &state).await { + let mint_result = match resolve_refresh_material(Some(credentials), &state).await { Ok(transient_state) => mint_credential(&transient_state).await, Err(err) => Err(err), }; @@ -707,46 +745,54 @@ pub async fn refresh_provider_credential( { state.secret_material_keys.push("refresh_token".to_string()); } - if let Some(credentials) = credentials { - let material = - HashMap::from([("refresh_token".to_string(), refresh_token.clone())]); - let staging_id = format!( - "{}-refresh-material-{}", - state.object_id(), - uuid::Uuid::new_v4() - ); - staged_refresh_token_handles = credentials - .store_refresh_material_with_object_id( - refresh_material_scope(&state), - &staging_id, - &material, - &HashMap::new(), - ) - .await?; - let handle = staged_refresh_token_handles - .get("refresh_token") - .cloned() - .ok_or_else(|| { - Status::internal( - "credential driver did not return a refresh-token handle", - ) - })?; - if let Some(previous) = state - .secret_material_handles - .insert("refresh_token".to_string(), handle) - { - state - .pending_secret_deletions - .insert("refresh_token".to_string(), previous); + let material = + HashMap::from([("refresh_token".to_string(), refresh_token.clone())]); + let staging_id = format!( + "{}-refresh-material-{}", + state.object_id(), + uuid::Uuid::new_v4() + ); + staged_refresh_token_handles = match credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + &staging_id, + &material, + &HashMap::new(), + ) + .await + { + Ok(handles) => handles, + Err(store_err) => { + let err = Status::failed_precondition(format!( + "the OAuth provider rotated the refresh token, but the replacement could not be stored; the grant must be re-authorized: {}", + store_err.message() + )); + persist_refresh_error_state(store, &mut state, expected_version, &err) + .await?; + return Err(err); } - state.material.remove("refresh_token"); - } else { - // Test-only and legacy callers without a credential runtime - // retain the pre-driver behavior. - state - .material - .insert("refresh_token".to_string(), refresh_token.clone()); + }; + let Some(handle) = staged_refresh_token_handles.get("refresh_token").cloned() + else { + let err = Status::failed_precondition( + "the OAuth provider rotated the refresh token, but the credential driver returned no replacement handle; the grant must be re-authorized", + ); + cleanup_staged_refresh_material_handles( + credentials, + &state, + &staged_refresh_token_handles, + ) + .await; + persist_refresh_error_state(store, &mut state, expected_version, &err).await?; + return Err(err); + }; + if let Some(previous) = state + .secret_material_handles + .insert("refresh_token".to_string(), handle) + { + enqueue_pending_secret_deletion(&mut state, "refresh_token", previous); } + state.material.remove("refresh_token"); } state.expires_at_ms = minted.expires_at_ms; state.next_refresh_at_ms = next_refresh_at_ms( @@ -776,9 +822,7 @@ pub async fn refresh_provider_credential( { Ok(Some(new_version)) => new_version, Ok(None) => { - if let Some(credentials) = credentials - && !staged_refresh_token_handles.is_empty() - { + if !staged_refresh_token_handles.is_empty() { cleanup_staged_refresh_material_handles( credentials, &state, @@ -797,16 +841,13 @@ pub async fn refresh_provider_credential( )); } Err(err) => { - if let Some(credentials) = credentials - && !staged_refresh_token_handles.is_empty() - { - cleanup_staged_refresh_material_handles( - credentials, - &state, - &staged_refresh_token_handles, - ) - .await; - } + // The replacement refresh token is already in credential + // storage. Retry the same CAS with error/backoff state so a + // transient database failure does not discard the only + // upstream-valid grant. If that also fails, leave the + // staged object intact for operator recovery rather than + // deleting an irreplaceable rotated token. + persist_refresh_error_state(store, &mut state, expected_version, &err).await?; return Err(err); } }; @@ -815,7 +856,7 @@ pub async fn refresh_provider_credential( if let Err(err) = apply_minted_credential( store, workspace, - credentials, + Some(credentials), compute, &provider, credential_key, @@ -823,13 +864,9 @@ pub async fn refresh_provider_credential( ) .await { - state.status = "error".to_string(); - state.last_error = err.message().to_string(); - state.next_refresh_at_ms = - now_ms.saturating_add(REFRESH_ERROR_RETRY_SECONDS.saturating_mul(1000)); // Reflect the failure on the state we just wrote; skip silently // if it was deleted concurrently (it is not recreated). - persist_refresh_state_if_current(store, &state, new_version).await?; + persist_refresh_error_state(store, &mut state, new_version, &err).await?; warn!( provider = %state.provider_name, credential_key = %state.credential_key, @@ -853,9 +890,13 @@ pub async fn refresh_provider_credential( "provider credential refresh completed" ); if !state.pending_secret_deletions.is_empty() - && let Err(err) = - cleanup_pending_secret_deletions(store, credentials, &mut state, new_version) - .await + && let Err(err) = cleanup_pending_secret_deletions( + store, + Some(credentials), + &mut state, + new_version, + ) + .await { warn!( provider = %state.provider_name, @@ -868,11 +909,7 @@ pub async fn refresh_provider_credential( } Err(err) => { let now_ms = current_time_ms(); - state.status = "error".to_string(); - state.last_error = err.message().to_string(); - state.next_refresh_at_ms = - now_ms.saturating_add(REFRESH_ERROR_RETRY_SECONDS.saturating_mul(1000)); - persist_refresh_state_if_current(store, &state, expected_version).await?; + persist_refresh_error_state(store, &mut state, expected_version, &err).await?; warn!( provider = %state.provider_name, credential_key = %state.credential_key, @@ -1566,6 +1603,49 @@ async fn run_refresh_worker_tick( due_count, rotation_requested_count, "provider credential refresh worker sweep" ); for state in states { + if state + .metadata + .as_ref() + .is_some_and(|metadata| metadata.deletion_timestamp_ms != 0) + { + let Some(credentials) = credentials else { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + "cannot finalize tombstoned provider refresh without credential runtime" + ); + continue; + }; + if let Err(err) = delete_refresh_state_with_credentials( + store, + credentials, + state.object_workspace(), + &state.provider_id, + &state.credential_key, + ) + .await + { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + error = %err, + "failed to finalize tombstoned provider refresh; retrying on the next sweep" + ); + } + continue; + } + let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) + .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); + if !is_gateway_mintable_strategy(strategy) { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + strategy = %refresh_strategy_name(state.strategy), + status = %state.status, + "skipping non-gateway-mintable provider credential refresh state" + ); + continue; + } let mut state = match migrate_inline_secret_material(store, credentials, &state).await { Ok(state) => state, Err(err) => { @@ -1589,19 +1669,9 @@ async fn run_refresh_worker_tick( provider = %state.provider_name, credential_key = %state.credential_key, error = %err, - "provider refresh material cleanup failed" + "provider refresh material cleanup failed; continuing with live refresh" ); - continue; } - if state - .metadata - .as_ref() - .is_some_and(|metadata| metadata.deletion_timestamp_ms != 0) - { - continue; - } - let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) - .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); let due = state.next_refresh_at_ms <= 0 || state.next_refresh_at_ms <= now_ms; let rotation_requested = state.status == "rotation_requested"; info!( @@ -1621,16 +1691,14 @@ async fn run_refresh_worker_tick( if !due && !rotation_requested { continue; } - if !is_gateway_mintable_strategy(strategy) { + let Some(credentials) = credentials else { warn!( provider = %state.provider_name, credential_key = %state.credential_key, - strategy = %refresh_strategy_name(state.strategy), - status = %state.status, - "skipping non-gateway-mintable provider credential refresh state" + "cannot refresh provider credential without credential runtime" ); continue; - } + }; info!( provider = %state.provider_name, credential_key = %state.credential_key, @@ -1665,17 +1733,19 @@ async fn run_refresh_worker_tick( #[cfg(test)] mod tests { use super::{ - NewRefreshStateConfig, delete_refresh_state, effective_authorization_epoch, - get_refresh_state, list_all_refresh_states, list_refresh_states_for_provider, - new_refresh_state, put_refresh_state, refresh_provider_credential, refresh_state_name, - refresh_strategy_name, run_refresh_worker_tick, seconds_until_ms, + NewRefreshStateConfig, delete_refresh_state_with_credentials, + effective_authorization_epoch, enqueue_pending_secret_deletion, get_refresh_state, + list_all_refresh_states, list_refresh_states_for_provider, migrate_inline_secret_material, + new_refresh_state, put_refresh_state, refresh_material_scope, refresh_provider_credential, + refresh_state_name, refresh_strategy_name, run_refresh_worker_tick, seconds_until_ms, + validate_secret_material_references, }; use crate::credentials::CredentialRuntime; use crate::persistence::{current_time_ms, test_store}; use openshell_core::Config; use openshell_core::proto::datamodel::v1::ObjectMeta; use openshell_core::proto::{ - Provider, ProviderCredentialRefreshStrategy, Sandbox, SandboxSpec, + CredentialHandle, Provider, ProviderCredentialRefreshStrategy, Sandbox, SandboxSpec, StoredProviderCredentialRefreshState, }; use openshell_core::{ObjectId, ObjectName, ObjectWorkspace}; @@ -1683,6 +1753,11 @@ mod tests { use wiremock::matchers::{body_string_contains, method, path}; use wiremock::{Mock, MockServer, ResponseTemplate}; + fn test_credentials() -> CredentialRuntime { + CredentialRuntime::from_config(&Config::new(None).with_credential_drivers(["test-static"])) + .expect("test credential runtime") + } + #[test] fn refresh_state_name_preserves_distinct_credential_keys() { let provider_id = "provider-id"; @@ -1726,6 +1801,76 @@ mod tests { assert_eq!(all[0].metadata.as_ref().unwrap().resource_version, 1); } + #[tokio::test] + async fn superseded_inline_material_migration_cleans_staged_handle() { + let store = test_store().await; + let provider = provider("migration-race", "outlook"); + let state = new_refresh_state( + &provider, + "default", + "MS_GRAPH_ACCESS_TOKEN", + NewRefreshStateConfig { + strategy: ProviderCredentialRefreshStrategy::Oauth2ClientCredentials, + material: HashMap::from([ + ("client_id".to_string(), "client-id".to_string()), + ("client_secret".to_string(), "client-secret".to_string()), + ]), + secret_material_keys: vec!["client_secret".to_string()], + expires_at_ms: 0, + token_url: "https://issuer.example/token".to_string(), + scopes: Vec::new(), + refresh_before_seconds: 30, + max_lifetime_seconds: 60, + additional_output_keys: HashMap::new(), + }, + ) + .unwrap(); + put_refresh_state(&store, &state).await.unwrap(); + let state = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + let credentials = test_credentials(); + let (store_hit, release_store) = credentials.gate_next_store(); + + let migration = migrate_inline_secret_material(&store, Some(&credentials), &state); + let supersede = async { + store_hit.await.unwrap(); + let mut winner = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + winner.last_error = "won-by-concurrent-writer".to_string(); + put_refresh_state(&store, &winner).await.unwrap(); + release_store.send(()).unwrap(); + }; + let (result, ()) = tokio::join!(migration, supersede); + + assert_eq!(result.unwrap_err().code(), tonic::Code::Aborted); + assert_eq!(credentials.stored_credential_count(), Some(0)); + let winner = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert_eq!(winner.last_error, "won-by-concurrent-writer"); + assert!(winner.secret_material_handles.is_empty()); + } + #[test] fn new_refresh_configuration_rotates_authorization_epoch_and_legacy_state_is_stable() { let provider = Provider { @@ -1787,6 +1932,62 @@ mod tests { assert_eq!(refresh_strategy_name(i32::MAX), "unspecified"); } + #[test] + fn pending_secret_deletions_preserve_multiple_generations_for_one_key() { + let mut state = StoredProviderCredentialRefreshState::default(); + for handle in ["first", "second"] { + enqueue_pending_secret_deletion( + &mut state, + "refresh_token", + CredentialHandle { + driver: "test-static".to_string(), + handle: handle.to_string(), + metadata: HashMap::new(), + }, + ); + } + + assert_eq!(state.pending_secret_deletions.len(), 2); + assert_eq!( + state.pending_secret_deletions[0] + .handle + .as_ref() + .unwrap() + .handle, + "first" + ); + assert_eq!( + state.pending_secret_deletions[1] + .handle + .as_ref() + .unwrap() + .handle, + "second" + ); + } + + #[test] + fn refresh_rejects_secret_material_lost_by_mixed_version_gateway() { + let mut state = StoredProviderCredentialRefreshState { + secret_material_keys: vec!["refresh_token".to_string()], + ..Default::default() + }; + let err = validate_secret_material_references(&state).unwrap_err(); + assert_eq!(err.code(), tonic::Code::FailedPrecondition); + assert!(err.message().contains("mixed-version gateway")); + assert!(err.message().contains("refresh_token")); + + state.secret_material_handles.insert( + "refresh_token".to_string(), + CredentialHandle { + driver: "test-static".to_string(), + handle: "stored-token".to_string(), + metadata: HashMap::new(), + }, + ); + validate_secret_material_references(&state).unwrap(); + } + #[tokio::test] async fn oauth2_client_credentials_refresh_mints_and_persists_access_token() { let mock_server = MockServer::start().await; @@ -1831,11 +2032,12 @@ mod tests { .unwrap(); put_refresh_state(&store, &state).await.unwrap(); let authorization_epoch = state.authorization_epoch.clone(); + let credentials = test_credentials(); let refreshed = refresh_provider_credential( &store, "default", - None, + &credentials, None, "my-graph", "MS_GRAPH_ACCESS_TOKEN", @@ -1854,8 +2056,12 @@ mod tests { .await .unwrap() .unwrap(); + let resolved = credentials + .resolve_provider_handles(&stored, current_time_ms()) + .await + .unwrap(); assert_eq!( - stored.credentials.get("MS_GRAPH_ACCESS_TOKEN"), + resolved.values.get("MS_GRAPH_ACCESS_TOKEN"), Some(&"minted-graph-token".to_string()) ); assert_eq!( @@ -1908,7 +2114,7 @@ mod tests { let refreshed = refresh_provider_credential( &store, "default", - Some(&credentials), + &credentials, None, "my-stored-graph", "MS_GRAPH_ACCESS_TOKEN", @@ -2021,11 +2227,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let err = refresh_provider_credential( &store, "default", - None, + &credentials, None, "refreshing-graph", "MS_GRAPH_ACCESS_TOKEN", @@ -2110,7 +2317,7 @@ mod tests { let refreshed = refresh_provider_credential( &store, "default", - Some(&credentials), + &credentials, None, "my-delegated-graph", "MS_GRAPH_ACCESS_TOKEN", @@ -2161,7 +2368,7 @@ mod tests { assert_eq!( credentials .resolve_refresh_material( - super::refresh_material_scope(&stored_state), + refresh_material_scope(&stored_state), &stored_state.secret_material_handles, ) .await @@ -2182,6 +2389,185 @@ mod tests { ); } + #[tokio::test] + async fn refresh_continues_when_pending_secret_cleanup_temporarily_fails() { + let mock_server = MockServer::start().await; + Mock::given(method("POST")) + .and(path("/token")) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "access_token": "minted-after-cleanup-failure", + "expires_in": 3600, + "token_type": "Bearer" + }))) + .mount(&mock_server) + .await; + + let store = test_store().await; + let provider = provider("cleanup-retry", "outlook"); + store.put_message(&provider).await.unwrap(); + let credentials = test_credentials(); + let mut state = new_refresh_state( + &provider, + "default", + "MS_GRAPH_ACCESS_TOKEN", + NewRefreshStateConfig { + strategy: ProviderCredentialRefreshStrategy::Oauth2ClientCredentials, + material: HashMap::from([ + ("client_id".to_string(), "client-id".to_string()), + ("client_secret".to_string(), "client-secret".to_string()), + ]), + secret_material_keys: vec!["client_secret".to_string()], + expires_at_ms: 0, + token_url: format!("{}/token", mock_server.uri()), + scopes: Vec::new(), + refresh_before_seconds: 30, + max_lifetime_seconds: 60, + additional_output_keys: HashMap::new(), + }, + ) + .unwrap(); + let old = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + "old-refresh-object", + &HashMap::from([("client_secret".to_string(), "obsolete".to_string())]), + &HashMap::new(), + ) + .await + .unwrap() + .remove("client_secret") + .unwrap(); + enqueue_pending_secret_deletion(&mut state, "client_secret", old); + put_refresh_state(&store, &state).await.unwrap(); + credentials.fail_next_delete(); + + let refreshed = refresh_provider_credential( + &store, + "default", + &credentials, + None, + "cleanup-retry", + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap(); + + assert_eq!(refreshed.status, "refreshed"); + assert!(refreshed.pending_secret_deletions.is_empty()); + let stored = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert!(stored.pending_secret_deletions.is_empty()); + assert_eq!( + credentials.stored_credential_count(), + Some(2), + "the current client secret and minted access token remain" + ); + } + + #[tokio::test] + async fn rotated_refresh_token_store_failure_persists_error_and_backoff() { + let mock_server = MockServer::start().await; + Mock::given(method("POST")) + .and(path("/token")) + .respond_with(ResponseTemplate::new(200).set_body_json(serde_json::json!({ + "access_token": "access-token-that-must-not-be-applied", + "refresh_token": "replacement-refresh-token", + "expires_in": 3600, + "token_type": "Bearer" + }))) + .mount(&mock_server) + .await; + + let store = test_store().await; + let provider = provider("rotation-store-failure", "outlook"); + store.put_message(&provider).await.unwrap(); + let credentials = test_credentials(); + let mut state = new_refresh_state( + &provider, + "default", + "MS_GRAPH_ACCESS_TOKEN", + NewRefreshStateConfig { + strategy: ProviderCredentialRefreshStrategy::Oauth2RefreshToken, + material: HashMap::from([ + ("client_id".to_string(), "client-id".to_string()), + ("refresh_token".to_string(), "old-refresh-token".to_string()), + ]), + secret_material_keys: vec!["refresh_token".to_string()], + expires_at_ms: 0, + token_url: format!("{}/token", mock_server.uri()), + scopes: Vec::new(), + refresh_before_seconds: 30, + max_lifetime_seconds: 60, + additional_output_keys: HashMap::new(), + }, + ) + .unwrap(); + state.secret_material_handles = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + "original-grant", + &HashMap::from([("refresh_token".to_string(), "old-refresh-token".to_string())]), + &HashMap::new(), + ) + .await + .unwrap(); + state.material.remove("refresh_token"); + put_refresh_state(&store, &state).await.unwrap(); + credentials.fail_next_store(); + let before = current_time_ms(); + + let err = refresh_provider_credential( + &store, + "default", + &credentials, + None, + "rotation-store-failure", + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap_err(); + + assert_eq!(err.code(), tonic::Code::FailedPrecondition); + assert!(err.message().contains("must be re-authorized")); + let stored = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert_eq!(stored.status, "error"); + assert!(stored.last_error.contains("must be re-authorized")); + assert!(stored.next_refresh_at_ms > before); + assert_eq!(credentials.stored_credential_count(), Some(1)); + assert_eq!( + credentials + .resolve_refresh_material( + refresh_material_scope(&stored), + &stored.secret_material_handles, + ) + .await + .unwrap() + .get("refresh_token"), + Some(&"old-refresh-token".to_string()) + ); + let stored_provider = store + .get_message_by_name::("default", "rotation-store-failure") + .await + .unwrap() + .unwrap(); + assert!(stored_provider.credential_handles.is_empty()); + } + #[tokio::test] async fn google_service_account_refresh_mints_and_persists_access_token() { let mock_server = MockServer::start().await; @@ -2226,11 +2612,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let refreshed = refresh_provider_credential( &store, "default", - None, + &credentials, None, "my-drive", "GOOGLE_DRIVE_ACCESS_TOKEN", @@ -2245,8 +2632,12 @@ mod tests { .await .unwrap() .unwrap(); + let resolved = credentials + .resolve_provider_handles(&stored, current_time_ms()) + .await + .unwrap(); assert_eq!( - stored.credentials.get("GOOGLE_DRIVE_ACCESS_TOKEN"), + resolved.values.get("GOOGLE_DRIVE_ACCESS_TOKEN"), Some(&"minted-drive-token".to_string()) ); } @@ -2301,6 +2692,62 @@ mod tests { ); } + #[tokio::test] + async fn refresh_worker_finalizes_tombstoned_refresh_material() { + let store = test_store().await; + let provider = provider("tombstoned-refresh", "outlook"); + store.put_message(&provider).await.unwrap(); + let credentials = test_credentials(); + let mut state = new_refresh_state( + &provider, + "default", + "MS_GRAPH_ACCESS_TOKEN", + NewRefreshStateConfig { + strategy: ProviderCredentialRefreshStrategy::Oauth2RefreshToken, + material: HashMap::from([("refresh_token".to_string(), "delete-me".to_string())]), + secret_material_keys: vec!["refresh_token".to_string()], + expires_at_ms: 0, + token_url: "https://issuer.example/token".to_string(), + scopes: Vec::new(), + refresh_before_seconds: 30, + max_lifetime_seconds: 60, + additional_output_keys: HashMap::new(), + }, + ) + .unwrap(); + state.secret_material_handles = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + "tombstoned-grant", + &state.material, + &HashMap::new(), + ) + .await + .unwrap(); + state.material.clear(); + state.metadata.as_mut().unwrap().deletion_timestamp_ms = current_time_ms(); + state.status = "deleting".to_string(); + put_refresh_state(&store, &state).await.unwrap(); + assert_eq!(credentials.stored_credential_count(), Some(1)); + + run_refresh_worker_tick(&store, Some(&credentials), None) + .await + .unwrap(); + + assert!( + get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .is_none() + ); + assert_eq!(credentials.stored_credential_count(), Some(0)); + } + /// The worker ticks on a timer with no inbound request, so without a span /// of its own its store reads export as anonymous single-span traces. #[tokio::test] @@ -2428,11 +2875,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let refreshed = refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-sts-test", "AWS_ACCESS_KEY_ID", @@ -2447,16 +2895,20 @@ mod tests { .await .unwrap() .unwrap(); + let resolved = credentials + .resolve_provider_handles(&stored, current_time_ms()) + .await + .unwrap(); assert_eq!( - stored.credentials.get("AWS_ACCESS_KEY_ID"), + resolved.values.get("AWS_ACCESS_KEY_ID"), Some(&"ASIAMOCKKEY".to_string()) ); assert_eq!( - stored.credentials.get("AWS_SECRET_ACCESS_KEY"), + resolved.values.get("AWS_SECRET_ACCESS_KEY"), Some(&"MockSecretAccessKey123".to_string()) ); assert_eq!( - stored.credentials.get("AWS_SESSION_TOKEN"), + resolved.values.get("AWS_SESSION_TOKEN"), Some(&"MockSessionTokenXYZ".to_string()) ); } @@ -2526,11 +2978,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-sts-custom", "AWS_ACCESS_KEY_ID", @@ -2543,19 +2996,23 @@ mod tests { .await .unwrap() .unwrap(); + let resolved = credentials + .resolve_provider_handles(&stored, current_time_ms()) + .await + .unwrap(); assert_eq!( - stored.credentials.get("AWS_ACCESS_KEY_ID"), + resolved.values.get("AWS_ACCESS_KEY_ID"), Some(&"ASIAMOCKKEY".to_string()) ); assert_eq!( - stored.credentials.get("CUSTOM_SECRET"), + resolved.values.get("CUSTOM_SECRET"), Some(&"MockSecretAccessKey123".to_string()) ); assert_eq!( - stored.credentials.get("CUSTOM_SESSION"), + resolved.values.get("CUSTOM_SESSION"), Some(&"MockSessionTokenXYZ".to_string()) ); - assert!(!stored.credentials.contains_key("AWS_SECRET_ACCESS_KEY")); + assert!(!resolved.values.contains_key("AWS_SECRET_ACCESS_KEY")); } #[tokio::test] @@ -2603,11 +3060,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let err = refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-sts-partial", "AWS_ACCESS_KEY_ID", @@ -2944,11 +3402,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let refreshed = refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-sts-session", "AWS_ACCESS_KEY_ID", @@ -2961,8 +3420,12 @@ mod tests { .await .unwrap() .unwrap(); + let resolved = credentials + .resolve_provider_handles(&stored, current_time_ms()) + .await + .unwrap(); assert_eq!( - stored.credentials.get("AWS_ACCESS_KEY_ID"), + resolved.values.get("AWS_ACCESS_KEY_ID"), Some(&"ASIAMOCKKEY".to_string()) ); } @@ -3013,11 +3476,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let err = refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-sts-lonesession", "AWS_ACCESS_KEY_ID", @@ -3100,11 +3564,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let rotate = refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-race", "AWS_ACCESS_KEY_ID", @@ -3118,9 +3583,15 @@ mod tests { { return; } - delete_refresh_state(&store, "default", &provider_id, "AWS_ACCESS_KEY_ID") - .await - .unwrap(); + delete_refresh_state_with_credentials( + &store, + &credentials, + "default", + &provider_id, + "AWS_ACCESS_KEY_ID", + ) + .await + .unwrap(); let _ = release_tx.send(()); }; let (rotate_result, ()) = tokio::join!(rotate, interfere); @@ -3221,11 +3692,12 @@ mod tests { ) .unwrap(); put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); let rotate = refresh_provider_credential( &store, "default", - None, + &credentials, None, "aws-superseded", "AWS_ACCESS_KEY_ID", diff --git a/docs/sandboxes/providers-v2.mdx b/docs/sandboxes/providers-v2.mdx index 9aa282a4a3..9c4315ce42 100644 --- a/docs/sandboxes/providers-v2.mdx +++ b/docs/sandboxes/providers-v2.mdx @@ -585,6 +585,10 @@ and injects it into every gateway pod when no external credential driver is enab a shared database with the default encrypted store, or choose a shared backend such as `kubernetes-secrets` or `vault`. +Every `secret_material_keys` entry must name a key supplied in `material` in the +same configure request. Clients submit secret values, not internal credential +handles. + Provider records that already contain inline database credentials remain readable for upgrade compatibility. New provider create/update requests store credential values through the active credential driver and persist only handles. diff --git a/proto/openshell.proto b/proto/openshell.proto index f804aae695..2f0c1ae34c 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -1606,9 +1606,18 @@ message StoredProviderCredentialRefreshState { // values exist in gateway memory for the duration of one mint operation. map secret_material_handles = 19; // Handles replaced by reconfiguration or issuer-driven refresh-token - // rotation. Cleanup is retried by the refresh worker so a gateway crash or - // temporary credential-backend outage does not lose the deletion reference. - map pending_secret_deletions = 20; + // rotation. This is a repeated entry rather than a material-keyed map so + // multiple superseded generations of the same material remain recoverable. + // Cleanup is retried by the refresh worker so a gateway crash or temporary + // credential-backend outage does not lose the deletion reference. + repeated StoredRefreshMaterialDeletion pending_secret_deletions = 20; +} + +message StoredRefreshMaterialDeletion { + // Original material name used to derive the credential driver's storage key. + string material_key = 1; + // Opaque handle for the superseded secret object. + openshell.datamodel.v1.CredentialHandle handle = 2; } message GetProviderRefreshStatusRequest { diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index bf3e9577bd..365929c885 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -5866,9 +5866,11 @@ type StoredProviderCredentialRefreshState struct { // values exist in gateway memory for the duration of one mint operation. SecretMaterialHandles map[string]*datamodelv1.CredentialHandle `protobuf:"bytes,19,rep,name=secret_material_handles,json=secretMaterialHandles,proto3" json:"secret_material_handles,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // Handles replaced by reconfiguration or issuer-driven refresh-token - // rotation. Cleanup is retried by the refresh worker so a gateway crash or - // temporary credential-backend outage does not lose the deletion reference. - PendingSecretDeletions map[string]*datamodelv1.CredentialHandle `protobuf:"bytes,20,rep,name=pending_secret_deletions,json=pendingSecretDeletions,proto3" json:"pending_secret_deletions,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // rotation. This is a repeated entry rather than a material-keyed map so + // multiple superseded generations of the same material remain recoverable. + // Cleanup is retried by the refresh worker so a gateway crash or temporary + // credential-backend outage does not lose the deletion reference. + PendingSecretDeletions []*StoredRefreshMaterialDeletion `protobuf:"bytes,20,rep,name=pending_secret_deletions,json=pendingSecretDeletions,proto3" json:"pending_secret_deletions,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -6036,13 +6038,67 @@ func (x *StoredProviderCredentialRefreshState) GetSecretMaterialHandles() map[st return nil } -func (x *StoredProviderCredentialRefreshState) GetPendingSecretDeletions() map[string]*datamodelv1.CredentialHandle { +func (x *StoredProviderCredentialRefreshState) GetPendingSecretDeletions() []*StoredRefreshMaterialDeletion { if x != nil { return x.PendingSecretDeletions } return nil } +type StoredRefreshMaterialDeletion struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Original material name used to derive the credential driver's storage key. + MaterialKey string `protobuf:"bytes,1,opt,name=material_key,json=materialKey,proto3" json:"material_key,omitempty"` + // Opaque handle for the superseded secret object. + Handle *datamodelv1.CredentialHandle `protobuf:"bytes,2,opt,name=handle,proto3" json:"handle,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *StoredRefreshMaterialDeletion) Reset() { + *x = StoredRefreshMaterialDeletion{} + mi := &file_openshell_proto_msgTypes[81] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *StoredRefreshMaterialDeletion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StoredRefreshMaterialDeletion) ProtoMessage() {} + +func (x *StoredRefreshMaterialDeletion) ProtoReflect() protoreflect.Message { + mi := &file_openshell_proto_msgTypes[81] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StoredRefreshMaterialDeletion.ProtoReflect.Descriptor instead. +func (*StoredRefreshMaterialDeletion) Descriptor() ([]byte, []int) { + return file_openshell_proto_rawDescGZIP(), []int{81} +} + +func (x *StoredRefreshMaterialDeletion) GetMaterialKey() string { + if x != nil { + return x.MaterialKey + } + return "" +} + +func (x *StoredRefreshMaterialDeletion) GetHandle() *datamodelv1.CredentialHandle { + if x != nil { + return x.Handle + } + return nil +} + type GetProviderRefreshStatusRequest struct { state protoimpl.MessageState `protogen:"open.v1"` Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` @@ -6055,7 +6111,7 @@ type GetProviderRefreshStatusRequest struct { func (x *GetProviderRefreshStatusRequest) Reset() { *x = GetProviderRefreshStatusRequest{} - mi := &file_openshell_proto_msgTypes[81] + mi := &file_openshell_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6067,7 +6123,7 @@ func (x *GetProviderRefreshStatusRequest) String() string { func (*GetProviderRefreshStatusRequest) ProtoMessage() {} func (x *GetProviderRefreshStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[81] + mi := &file_openshell_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6080,7 +6136,7 @@ func (x *GetProviderRefreshStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRefreshStatusRequest.ProtoReflect.Descriptor instead. func (*GetProviderRefreshStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{81} + return file_openshell_proto_rawDescGZIP(), []int{82} } func (x *GetProviderRefreshStatusRequest) GetProvider() string { @@ -6113,7 +6169,7 @@ type GetProviderRefreshStatusResponse struct { func (x *GetProviderRefreshStatusResponse) Reset() { *x = GetProviderRefreshStatusResponse{} - mi := &file_openshell_proto_msgTypes[82] + mi := &file_openshell_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6125,7 +6181,7 @@ func (x *GetProviderRefreshStatusResponse) String() string { func (*GetProviderRefreshStatusResponse) ProtoMessage() {} func (x *GetProviderRefreshStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[82] + mi := &file_openshell_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6138,7 +6194,7 @@ func (x *GetProviderRefreshStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetProviderRefreshStatusResponse.ProtoReflect.Descriptor instead. func (*GetProviderRefreshStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{82} + return file_openshell_proto_rawDescGZIP(), []int{83} } func (x *GetProviderRefreshStatusResponse) GetCredentials() []*ProviderCredentialRefreshStatus { @@ -6167,7 +6223,7 @@ type ConfigureProviderRefreshRequest struct { func (x *ConfigureProviderRefreshRequest) Reset() { *x = ConfigureProviderRefreshRequest{} - mi := &file_openshell_proto_msgTypes[83] + mi := &file_openshell_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6179,7 +6235,7 @@ func (x *ConfigureProviderRefreshRequest) String() string { func (*ConfigureProviderRefreshRequest) ProtoMessage() {} func (x *ConfigureProviderRefreshRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[83] + mi := &file_openshell_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6192,7 +6248,7 @@ func (x *ConfigureProviderRefreshRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureProviderRefreshRequest.ProtoReflect.Descriptor instead. func (*ConfigureProviderRefreshRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{83} + return file_openshell_proto_rawDescGZIP(), []int{84} } func (x *ConfigureProviderRefreshRequest) GetProvider() string { @@ -6253,7 +6309,7 @@ type ConfigureProviderRefreshResponse struct { func (x *ConfigureProviderRefreshResponse) Reset() { *x = ConfigureProviderRefreshResponse{} - mi := &file_openshell_proto_msgTypes[84] + mi := &file_openshell_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6265,7 +6321,7 @@ func (x *ConfigureProviderRefreshResponse) String() string { func (*ConfigureProviderRefreshResponse) ProtoMessage() {} func (x *ConfigureProviderRefreshResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[84] + mi := &file_openshell_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6278,7 +6334,7 @@ func (x *ConfigureProviderRefreshResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ConfigureProviderRefreshResponse.ProtoReflect.Descriptor instead. func (*ConfigureProviderRefreshResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{84} + return file_openshell_proto_rawDescGZIP(), []int{85} } func (x *ConfigureProviderRefreshResponse) GetStatus() *ProviderCredentialRefreshStatus { @@ -6300,7 +6356,7 @@ type RotateProviderCredentialRequest struct { func (x *RotateProviderCredentialRequest) Reset() { *x = RotateProviderCredentialRequest{} - mi := &file_openshell_proto_msgTypes[85] + mi := &file_openshell_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6312,7 +6368,7 @@ func (x *RotateProviderCredentialRequest) String() string { func (*RotateProviderCredentialRequest) ProtoMessage() {} func (x *RotateProviderCredentialRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[85] + mi := &file_openshell_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6325,7 +6381,7 @@ func (x *RotateProviderCredentialRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RotateProviderCredentialRequest.ProtoReflect.Descriptor instead. func (*RotateProviderCredentialRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{85} + return file_openshell_proto_rawDescGZIP(), []int{86} } func (x *RotateProviderCredentialRequest) GetProvider() string { @@ -6358,7 +6414,7 @@ type RotateProviderCredentialResponse struct { func (x *RotateProviderCredentialResponse) Reset() { *x = RotateProviderCredentialResponse{} - mi := &file_openshell_proto_msgTypes[86] + mi := &file_openshell_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6370,7 +6426,7 @@ func (x *RotateProviderCredentialResponse) String() string { func (*RotateProviderCredentialResponse) ProtoMessage() {} func (x *RotateProviderCredentialResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[86] + mi := &file_openshell_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6383,7 +6439,7 @@ func (x *RotateProviderCredentialResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RotateProviderCredentialResponse.ProtoReflect.Descriptor instead. func (*RotateProviderCredentialResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{86} + return file_openshell_proto_rawDescGZIP(), []int{87} } func (x *RotateProviderCredentialResponse) GetStatus() *ProviderCredentialRefreshStatus { @@ -6405,7 +6461,7 @@ type DeleteProviderRefreshRequest struct { func (x *DeleteProviderRefreshRequest) Reset() { *x = DeleteProviderRefreshRequest{} - mi := &file_openshell_proto_msgTypes[87] + mi := &file_openshell_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6417,7 +6473,7 @@ func (x *DeleteProviderRefreshRequest) String() string { func (*DeleteProviderRefreshRequest) ProtoMessage() {} func (x *DeleteProviderRefreshRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[87] + mi := &file_openshell_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6430,7 +6486,7 @@ func (x *DeleteProviderRefreshRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRefreshRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderRefreshRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{87} + return file_openshell_proto_rawDescGZIP(), []int{88} } func (x *DeleteProviderRefreshRequest) GetProvider() string { @@ -6463,7 +6519,7 @@ type DeleteProviderRefreshResponse struct { func (x *DeleteProviderRefreshResponse) Reset() { *x = DeleteProviderRefreshResponse{} - mi := &file_openshell_proto_msgTypes[88] + mi := &file_openshell_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6475,7 +6531,7 @@ func (x *DeleteProviderRefreshResponse) String() string { func (*DeleteProviderRefreshResponse) ProtoMessage() {} func (x *DeleteProviderRefreshResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[88] + mi := &file_openshell_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6488,7 +6544,7 @@ func (x *DeleteProviderRefreshResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderRefreshResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderRefreshResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{88} + return file_openshell_proto_rawDescGZIP(), []int{89} } func (x *DeleteProviderRefreshResponse) GetDeleted() bool { @@ -6528,7 +6584,7 @@ type ProviderProfile struct { func (x *ProviderProfile) Reset() { *x = ProviderProfile{} - mi := &file_openshell_proto_msgTypes[89] + mi := &file_openshell_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6540,7 +6596,7 @@ func (x *ProviderProfile) String() string { func (*ProviderProfile) ProtoMessage() {} func (x *ProviderProfile) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[89] + mi := &file_openshell_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6553,7 +6609,7 @@ func (x *ProviderProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfile.ProtoReflect.Descriptor instead. func (*ProviderProfile) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{89} + return file_openshell_proto_rawDescGZIP(), []int{90} } func (x *ProviderProfile) GetId() string { @@ -6658,7 +6714,7 @@ type StoredProviderProfile struct { func (x *StoredProviderProfile) Reset() { *x = StoredProviderProfile{} - mi := &file_openshell_proto_msgTypes[90] + mi := &file_openshell_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6670,7 +6726,7 @@ func (x *StoredProviderProfile) String() string { func (*StoredProviderProfile) ProtoMessage() {} func (x *StoredProviderProfile) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[90] + mi := &file_openshell_proto_msgTypes[91] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6683,7 +6739,7 @@ func (x *StoredProviderProfile) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredProviderProfile.ProtoReflect.Descriptor instead. func (*StoredProviderProfile) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{90} + return file_openshell_proto_rawDescGZIP(), []int{91} } func (x *StoredProviderProfile) GetMetadata() *datamodelv1.ObjectMeta { @@ -6710,7 +6766,7 @@ type ProviderProfileResponse struct { func (x *ProviderProfileResponse) Reset() { *x = ProviderProfileResponse{} - mi := &file_openshell_proto_msgTypes[91] + mi := &file_openshell_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6722,7 +6778,7 @@ func (x *ProviderProfileResponse) String() string { func (*ProviderProfileResponse) ProtoMessage() {} func (x *ProviderProfileResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[91] + mi := &file_openshell_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6735,7 +6791,7 @@ func (x *ProviderProfileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ProviderProfileResponse.ProtoReflect.Descriptor instead. func (*ProviderProfileResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{91} + return file_openshell_proto_rawDescGZIP(), []int{92} } func (x *ProviderProfileResponse) GetProfile() *ProviderProfile { @@ -6755,7 +6811,7 @@ type ListProviderProfilesResponse struct { func (x *ListProviderProfilesResponse) Reset() { *x = ListProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[92] + mi := &file_openshell_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6767,7 +6823,7 @@ func (x *ListProviderProfilesResponse) String() string { func (*ListProviderProfilesResponse) ProtoMessage() {} func (x *ListProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[92] + mi := &file_openshell_proto_msgTypes[93] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6780,7 +6836,7 @@ func (x *ListProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*ListProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{92} + return file_openshell_proto_rawDescGZIP(), []int{93} } func (x *ListProviderProfilesResponse) GetProfiles() []*ProviderProfile { @@ -6803,7 +6859,7 @@ type ImportProviderProfilesRequest struct { func (x *ImportProviderProfilesRequest) Reset() { *x = ImportProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[93] + mi := &file_openshell_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6815,7 +6871,7 @@ func (x *ImportProviderProfilesRequest) String() string { func (*ImportProviderProfilesRequest) ProtoMessage() {} func (x *ImportProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[93] + mi := &file_openshell_proto_msgTypes[94] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6828,7 +6884,7 @@ func (x *ImportProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*ImportProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{93} + return file_openshell_proto_rawDescGZIP(), []int{94} } func (x *ImportProviderProfilesRequest) GetProfiles() []*ProviderProfileImportItem { @@ -6857,7 +6913,7 @@ type ImportProviderProfilesResponse struct { func (x *ImportProviderProfilesResponse) Reset() { *x = ImportProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[94] + mi := &file_openshell_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6869,7 +6925,7 @@ func (x *ImportProviderProfilesResponse) String() string { func (*ImportProviderProfilesResponse) ProtoMessage() {} func (x *ImportProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[94] + mi := &file_openshell_proto_msgTypes[95] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6882,7 +6938,7 @@ func (x *ImportProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ImportProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*ImportProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{94} + return file_openshell_proto_rawDescGZIP(), []int{95} } func (x *ImportProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -6926,7 +6982,7 @@ type UpdateProviderProfilesRequest struct { func (x *UpdateProviderProfilesRequest) Reset() { *x = UpdateProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[95] + mi := &file_openshell_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6938,7 +6994,7 @@ func (x *UpdateProviderProfilesRequest) String() string { func (*UpdateProviderProfilesRequest) ProtoMessage() {} func (x *UpdateProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[95] + mi := &file_openshell_proto_msgTypes[96] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6951,7 +7007,7 @@ func (x *UpdateProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*UpdateProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{95} + return file_openshell_proto_rawDescGZIP(), []int{96} } func (x *UpdateProviderProfilesRequest) GetProfile() *ProviderProfileImportItem { @@ -6994,7 +7050,7 @@ type UpdateProviderProfilesResponse struct { func (x *UpdateProviderProfilesResponse) Reset() { *x = UpdateProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[96] + mi := &file_openshell_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7006,7 +7062,7 @@ func (x *UpdateProviderProfilesResponse) String() string { func (*UpdateProviderProfilesResponse) ProtoMessage() {} func (x *UpdateProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[96] + mi := &file_openshell_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7019,7 +7075,7 @@ func (x *UpdateProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*UpdateProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{96} + return file_openshell_proto_rawDescGZIP(), []int{97} } func (x *UpdateProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -7056,7 +7112,7 @@ type LintProviderProfilesRequest struct { func (x *LintProviderProfilesRequest) Reset() { *x = LintProviderProfilesRequest{} - mi := &file_openshell_proto_msgTypes[97] + mi := &file_openshell_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7068,7 +7124,7 @@ func (x *LintProviderProfilesRequest) String() string { func (*LintProviderProfilesRequest) ProtoMessage() {} func (x *LintProviderProfilesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[97] + mi := &file_openshell_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7081,7 +7137,7 @@ func (x *LintProviderProfilesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LintProviderProfilesRequest.ProtoReflect.Descriptor instead. func (*LintProviderProfilesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{97} + return file_openshell_proto_rawDescGZIP(), []int{98} } func (x *LintProviderProfilesRequest) GetProfiles() []*ProviderProfileImportItem { @@ -7109,7 +7165,7 @@ type LintProviderProfilesResponse struct { func (x *LintProviderProfilesResponse) Reset() { *x = LintProviderProfilesResponse{} - mi := &file_openshell_proto_msgTypes[98] + mi := &file_openshell_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7121,7 +7177,7 @@ func (x *LintProviderProfilesResponse) String() string { func (*LintProviderProfilesResponse) ProtoMessage() {} func (x *LintProviderProfilesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[98] + mi := &file_openshell_proto_msgTypes[99] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7134,7 +7190,7 @@ func (x *LintProviderProfilesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LintProviderProfilesResponse.ProtoReflect.Descriptor instead. func (*LintProviderProfilesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{98} + return file_openshell_proto_rawDescGZIP(), []int{99} } func (x *LintProviderProfilesResponse) GetDiagnostics() []*ProviderProfileDiagnostic { @@ -7161,7 +7217,7 @@ type DeleteProviderResponse struct { func (x *DeleteProviderResponse) Reset() { *x = DeleteProviderResponse{} - mi := &file_openshell_proto_msgTypes[99] + mi := &file_openshell_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7173,7 +7229,7 @@ func (x *DeleteProviderResponse) String() string { func (*DeleteProviderResponse) ProtoMessage() {} func (x *DeleteProviderResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[99] + mi := &file_openshell_proto_msgTypes[100] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7186,7 +7242,7 @@ func (x *DeleteProviderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{99} + return file_openshell_proto_rawDescGZIP(), []int{100} } func (x *DeleteProviderResponse) GetDeleted() bool { @@ -7209,7 +7265,7 @@ type DeleteProviderProfileRequest struct { func (x *DeleteProviderProfileRequest) Reset() { *x = DeleteProviderProfileRequest{} - mi := &file_openshell_proto_msgTypes[100] + mi := &file_openshell_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7221,7 +7277,7 @@ func (x *DeleteProviderProfileRequest) String() string { func (*DeleteProviderProfileRequest) ProtoMessage() {} func (x *DeleteProviderProfileRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[100] + mi := &file_openshell_proto_msgTypes[101] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7234,7 +7290,7 @@ func (x *DeleteProviderProfileRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderProfileRequest.ProtoReflect.Descriptor instead. func (*DeleteProviderProfileRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{100} + return file_openshell_proto_rawDescGZIP(), []int{101} } func (x *DeleteProviderProfileRequest) GetId() string { @@ -7261,7 +7317,7 @@ type DeleteProviderProfileResponse struct { func (x *DeleteProviderProfileResponse) Reset() { *x = DeleteProviderProfileResponse{} - mi := &file_openshell_proto_msgTypes[101] + mi := &file_openshell_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7273,7 +7329,7 @@ func (x *DeleteProviderProfileResponse) String() string { func (*DeleteProviderProfileResponse) ProtoMessage() {} func (x *DeleteProviderProfileResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[101] + mi := &file_openshell_proto_msgTypes[102] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7286,7 +7342,7 @@ func (x *DeleteProviderProfileResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteProviderProfileResponse.ProtoReflect.Descriptor instead. func (*DeleteProviderProfileResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{101} + return file_openshell_proto_rawDescGZIP(), []int{102} } func (x *DeleteProviderProfileResponse) GetDeleted() bool { @@ -7311,7 +7367,7 @@ type GetSandboxProviderEnvironmentRequest struct { func (x *GetSandboxProviderEnvironmentRequest) Reset() { *x = GetSandboxProviderEnvironmentRequest{} - mi := &file_openshell_proto_msgTypes[102] + mi := &file_openshell_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7323,7 +7379,7 @@ func (x *GetSandboxProviderEnvironmentRequest) String() string { func (*GetSandboxProviderEnvironmentRequest) ProtoMessage() {} func (x *GetSandboxProviderEnvironmentRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[102] + mi := &file_openshell_proto_msgTypes[103] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7336,7 +7392,7 @@ func (x *GetSandboxProviderEnvironmentRequest) ProtoReflect() protoreflect.Messa // Deprecated: Use GetSandboxProviderEnvironmentRequest.ProtoReflect.Descriptor instead. func (*GetSandboxProviderEnvironmentRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{102} + return file_openshell_proto_rawDescGZIP(), []int{103} } func (x *GetSandboxProviderEnvironmentRequest) GetSandboxId() string { @@ -7365,7 +7421,7 @@ type StaticCredentialEndpointBinding struct { func (x *StaticCredentialEndpointBinding) Reset() { *x = StaticCredentialEndpointBinding{} - mi := &file_openshell_proto_msgTypes[103] + mi := &file_openshell_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7377,7 +7433,7 @@ func (x *StaticCredentialEndpointBinding) String() string { func (*StaticCredentialEndpointBinding) ProtoMessage() {} func (x *StaticCredentialEndpointBinding) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[103] + mi := &file_openshell_proto_msgTypes[104] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7390,7 +7446,7 @@ func (x *StaticCredentialEndpointBinding) ProtoReflect() protoreflect.Message { // Deprecated: Use StaticCredentialEndpointBinding.ProtoReflect.Descriptor instead. func (*StaticCredentialEndpointBinding) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{103} + return file_openshell_proto_rawDescGZIP(), []int{104} } func (x *StaticCredentialEndpointBinding) GetHost() string { @@ -7434,7 +7490,7 @@ type StaticCredentialBinding struct { func (x *StaticCredentialBinding) Reset() { *x = StaticCredentialBinding{} - mi := &file_openshell_proto_msgTypes[104] + mi := &file_openshell_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7446,7 +7502,7 @@ func (x *StaticCredentialBinding) String() string { func (*StaticCredentialBinding) ProtoMessage() {} func (x *StaticCredentialBinding) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[104] + mi := &file_openshell_proto_msgTypes[105] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7459,7 +7515,7 @@ func (x *StaticCredentialBinding) ProtoReflect() protoreflect.Message { // Deprecated: Use StaticCredentialBinding.ProtoReflect.Descriptor instead. func (*StaticCredentialBinding) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{104} + return file_openshell_proto_rawDescGZIP(), []int{105} } func (x *StaticCredentialBinding) GetEndpoints() []*StaticCredentialEndpointBinding { @@ -7510,7 +7566,7 @@ type GetSandboxProviderEnvironmentResponse struct { func (x *GetSandboxProviderEnvironmentResponse) Reset() { *x = GetSandboxProviderEnvironmentResponse{} - mi := &file_openshell_proto_msgTypes[105] + mi := &file_openshell_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7522,7 +7578,7 @@ func (x *GetSandboxProviderEnvironmentResponse) String() string { func (*GetSandboxProviderEnvironmentResponse) ProtoMessage() {} func (x *GetSandboxProviderEnvironmentResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[105] + mi := &file_openshell_proto_msgTypes[106] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7535,7 +7591,7 @@ func (x *GetSandboxProviderEnvironmentResponse) ProtoReflect() protoreflect.Mess // Deprecated: Use GetSandboxProviderEnvironmentResponse.ProtoReflect.Descriptor instead. func (*GetSandboxProviderEnvironmentResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{105} + return file_openshell_proto_rawDescGZIP(), []int{106} } func (x *GetSandboxProviderEnvironmentResponse) GetEnvironment() map[string]string { @@ -7627,7 +7683,7 @@ type UpdateConfigRequest struct { func (x *UpdateConfigRequest) Reset() { *x = UpdateConfigRequest{} - mi := &file_openshell_proto_msgTypes[106] + mi := &file_openshell_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7639,7 +7695,7 @@ func (x *UpdateConfigRequest) String() string { func (*UpdateConfigRequest) ProtoMessage() {} func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[106] + mi := &file_openshell_proto_msgTypes[107] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7652,7 +7708,7 @@ func (x *UpdateConfigRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigRequest.ProtoReflect.Descriptor instead. func (*UpdateConfigRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{106} + return file_openshell_proto_rawDescGZIP(), []int{107} } func (x *UpdateConfigRequest) GetName() string { @@ -7742,7 +7798,7 @@ type PolicyMergeOperation struct { func (x *PolicyMergeOperation) Reset() { *x = PolicyMergeOperation{} - mi := &file_openshell_proto_msgTypes[107] + mi := &file_openshell_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7754,7 +7810,7 @@ func (x *PolicyMergeOperation) String() string { func (*PolicyMergeOperation) ProtoMessage() {} func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[107] + mi := &file_openshell_proto_msgTypes[108] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7767,7 +7823,7 @@ func (x *PolicyMergeOperation) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyMergeOperation.ProtoReflect.Descriptor instead. func (*PolicyMergeOperation) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{107} + return file_openshell_proto_rawDescGZIP(), []int{108} } func (x *PolicyMergeOperation) GetOperation() isPolicyMergeOperation_Operation { @@ -7881,7 +7937,7 @@ type AddNetworkRule struct { func (x *AddNetworkRule) Reset() { *x = AddNetworkRule{} - mi := &file_openshell_proto_msgTypes[108] + mi := &file_openshell_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7893,7 +7949,7 @@ func (x *AddNetworkRule) String() string { func (*AddNetworkRule) ProtoMessage() {} func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[108] + mi := &file_openshell_proto_msgTypes[109] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7906,7 +7962,7 @@ func (x *AddNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use AddNetworkRule.ProtoReflect.Descriptor instead. func (*AddNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{108} + return file_openshell_proto_rawDescGZIP(), []int{109} } func (x *AddNetworkRule) GetRuleName() string { @@ -7934,7 +7990,7 @@ type RemoveNetworkEndpoint struct { func (x *RemoveNetworkEndpoint) Reset() { *x = RemoveNetworkEndpoint{} - mi := &file_openshell_proto_msgTypes[109] + mi := &file_openshell_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7946,7 +8002,7 @@ func (x *RemoveNetworkEndpoint) String() string { func (*RemoveNetworkEndpoint) ProtoMessage() {} func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[109] + mi := &file_openshell_proto_msgTypes[110] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7959,7 +8015,7 @@ func (x *RemoveNetworkEndpoint) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkEndpoint.ProtoReflect.Descriptor instead. func (*RemoveNetworkEndpoint) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{109} + return file_openshell_proto_rawDescGZIP(), []int{110} } func (x *RemoveNetworkEndpoint) GetRuleName() string { @@ -7992,7 +8048,7 @@ type RemoveNetworkRule struct { func (x *RemoveNetworkRule) Reset() { *x = RemoveNetworkRule{} - mi := &file_openshell_proto_msgTypes[110] + mi := &file_openshell_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8004,7 +8060,7 @@ func (x *RemoveNetworkRule) String() string { func (*RemoveNetworkRule) ProtoMessage() {} func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[110] + mi := &file_openshell_proto_msgTypes[111] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8017,7 +8073,7 @@ func (x *RemoveNetworkRule) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkRule.ProtoReflect.Descriptor instead. func (*RemoveNetworkRule) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{110} + return file_openshell_proto_rawDescGZIP(), []int{111} } func (x *RemoveNetworkRule) GetRuleName() string { @@ -8038,7 +8094,7 @@ type AddDenyRules struct { func (x *AddDenyRules) Reset() { *x = AddDenyRules{} - mi := &file_openshell_proto_msgTypes[111] + mi := &file_openshell_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8050,7 +8106,7 @@ func (x *AddDenyRules) String() string { func (*AddDenyRules) ProtoMessage() {} func (x *AddDenyRules) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[111] + mi := &file_openshell_proto_msgTypes[112] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8063,7 +8119,7 @@ func (x *AddDenyRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddDenyRules.ProtoReflect.Descriptor instead. func (*AddDenyRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{111} + return file_openshell_proto_rawDescGZIP(), []int{112} } func (x *AddDenyRules) GetHost() string { @@ -8098,7 +8154,7 @@ type AddAllowRules struct { func (x *AddAllowRules) Reset() { *x = AddAllowRules{} - mi := &file_openshell_proto_msgTypes[112] + mi := &file_openshell_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8110,7 +8166,7 @@ func (x *AddAllowRules) String() string { func (*AddAllowRules) ProtoMessage() {} func (x *AddAllowRules) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[112] + mi := &file_openshell_proto_msgTypes[113] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8123,7 +8179,7 @@ func (x *AddAllowRules) ProtoReflect() protoreflect.Message { // Deprecated: Use AddAllowRules.ProtoReflect.Descriptor instead. func (*AddAllowRules) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{112} + return file_openshell_proto_rawDescGZIP(), []int{113} } func (x *AddAllowRules) GetHost() string { @@ -8157,7 +8213,7 @@ type RemoveNetworkBinary struct { func (x *RemoveNetworkBinary) Reset() { *x = RemoveNetworkBinary{} - mi := &file_openshell_proto_msgTypes[113] + mi := &file_openshell_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8169,7 +8225,7 @@ func (x *RemoveNetworkBinary) String() string { func (*RemoveNetworkBinary) ProtoMessage() {} func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[113] + mi := &file_openshell_proto_msgTypes[114] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8182,7 +8238,7 @@ func (x *RemoveNetworkBinary) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveNetworkBinary.ProtoReflect.Descriptor instead. func (*RemoveNetworkBinary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{113} + return file_openshell_proto_rawDescGZIP(), []int{114} } func (x *RemoveNetworkBinary) GetRuleName() string { @@ -8218,7 +8274,7 @@ type UpdateConfigResponse struct { func (x *UpdateConfigResponse) Reset() { *x = UpdateConfigResponse{} - mi := &file_openshell_proto_msgTypes[114] + mi := &file_openshell_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8230,7 +8286,7 @@ func (x *UpdateConfigResponse) String() string { func (*UpdateConfigResponse) ProtoMessage() {} func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[114] + mi := &file_openshell_proto_msgTypes[115] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8243,7 +8299,7 @@ func (x *UpdateConfigResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateConfigResponse.ProtoReflect.Descriptor instead. func (*UpdateConfigResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{114} + return file_openshell_proto_rawDescGZIP(), []int{115} } func (x *UpdateConfigResponse) GetVersion() uint32 { @@ -8298,7 +8354,7 @@ type GetSandboxPolicyStatusRequest struct { func (x *GetSandboxPolicyStatusRequest) Reset() { *x = GetSandboxPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[115] + mi := &file_openshell_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8310,7 +8366,7 @@ func (x *GetSandboxPolicyStatusRequest) String() string { func (*GetSandboxPolicyStatusRequest) ProtoMessage() {} func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[115] + mi := &file_openshell_proto_msgTypes[116] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8323,7 +8379,7 @@ func (x *GetSandboxPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{115} + return file_openshell_proto_rawDescGZIP(), []int{116} } func (x *GetSandboxPolicyStatusRequest) GetName() string { @@ -8367,7 +8423,7 @@ type GetSandboxPolicyStatusResponse struct { func (x *GetSandboxPolicyStatusResponse) Reset() { *x = GetSandboxPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[116] + mi := &file_openshell_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8379,7 +8435,7 @@ func (x *GetSandboxPolicyStatusResponse) String() string { func (*GetSandboxPolicyStatusResponse) ProtoMessage() {} func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[116] + mi := &file_openshell_proto_msgTypes[117] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8392,7 +8448,7 @@ func (x *GetSandboxPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*GetSandboxPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{116} + return file_openshell_proto_rawDescGZIP(), []int{117} } func (x *GetSandboxPolicyStatusResponse) GetRevision() *SandboxPolicyRevision { @@ -8426,7 +8482,7 @@ type ListSandboxPoliciesRequest struct { func (x *ListSandboxPoliciesRequest) Reset() { *x = ListSandboxPoliciesRequest{} - mi := &file_openshell_proto_msgTypes[117] + mi := &file_openshell_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8438,7 +8494,7 @@ func (x *ListSandboxPoliciesRequest) String() string { func (*ListSandboxPoliciesRequest) ProtoMessage() {} func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[117] + mi := &file_openshell_proto_msgTypes[118] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8451,7 +8507,7 @@ func (x *ListSandboxPoliciesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesRequest.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{117} + return file_openshell_proto_rawDescGZIP(), []int{118} } func (x *ListSandboxPoliciesRequest) GetName() string { @@ -8499,7 +8555,7 @@ type ListSandboxPoliciesResponse struct { func (x *ListSandboxPoliciesResponse) Reset() { *x = ListSandboxPoliciesResponse{} - mi := &file_openshell_proto_msgTypes[118] + mi := &file_openshell_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8511,7 +8567,7 @@ func (x *ListSandboxPoliciesResponse) String() string { func (*ListSandboxPoliciesResponse) ProtoMessage() {} func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[118] + mi := &file_openshell_proto_msgTypes[119] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8524,7 +8580,7 @@ func (x *ListSandboxPoliciesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListSandboxPoliciesResponse.ProtoReflect.Descriptor instead. func (*ListSandboxPoliciesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{118} + return file_openshell_proto_rawDescGZIP(), []int{119} } func (x *ListSandboxPoliciesResponse) GetRevisions() []*SandboxPolicyRevision { @@ -8551,7 +8607,7 @@ type ReportPolicyStatusRequest struct { func (x *ReportPolicyStatusRequest) Reset() { *x = ReportPolicyStatusRequest{} - mi := &file_openshell_proto_msgTypes[119] + mi := &file_openshell_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8563,7 +8619,7 @@ func (x *ReportPolicyStatusRequest) String() string { func (*ReportPolicyStatusRequest) ProtoMessage() {} func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[119] + mi := &file_openshell_proto_msgTypes[120] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8576,7 +8632,7 @@ func (x *ReportPolicyStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusRequest.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{119} + return file_openshell_proto_rawDescGZIP(), []int{120} } func (x *ReportPolicyStatusRequest) GetSandboxId() string { @@ -8616,7 +8672,7 @@ type ReportPolicyStatusResponse struct { func (x *ReportPolicyStatusResponse) Reset() { *x = ReportPolicyStatusResponse{} - mi := &file_openshell_proto_msgTypes[120] + mi := &file_openshell_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8628,7 +8684,7 @@ func (x *ReportPolicyStatusResponse) String() string { func (*ReportPolicyStatusResponse) ProtoMessage() {} func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[120] + mi := &file_openshell_proto_msgTypes[121] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8641,7 +8697,7 @@ func (x *ReportPolicyStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportPolicyStatusResponse.ProtoReflect.Descriptor instead. func (*ReportPolicyStatusResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{120} + return file_openshell_proto_rawDescGZIP(), []int{121} } // A versioned policy revision with metadata. @@ -8669,7 +8725,7 @@ type SandboxPolicyRevision struct { func (x *SandboxPolicyRevision) Reset() { *x = SandboxPolicyRevision{} - mi := &file_openshell_proto_msgTypes[121] + mi := &file_openshell_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8681,7 +8737,7 @@ func (x *SandboxPolicyRevision) String() string { func (*SandboxPolicyRevision) ProtoMessage() {} func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[121] + mi := &file_openshell_proto_msgTypes[122] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8694,7 +8750,7 @@ func (x *SandboxPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use SandboxPolicyRevision.ProtoReflect.Descriptor instead. func (*SandboxPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{121} + return file_openshell_proto_rawDescGZIP(), []int{122} } func (x *SandboxPolicyRevision) GetVersion() uint32 { @@ -8774,7 +8830,7 @@ type GetSandboxLogsRequest struct { func (x *GetSandboxLogsRequest) Reset() { *x = GetSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[122] + mi := &file_openshell_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8786,7 +8842,7 @@ func (x *GetSandboxLogsRequest) String() string { func (*GetSandboxLogsRequest) ProtoMessage() {} func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[122] + mi := &file_openshell_proto_msgTypes[123] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8799,7 +8855,7 @@ func (x *GetSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*GetSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{122} + return file_openshell_proto_rawDescGZIP(), []int{123} } func (x *GetSandboxLogsRequest) GetSandboxId() string { @@ -8857,7 +8913,7 @@ type PushSandboxLogsRequest struct { func (x *PushSandboxLogsRequest) Reset() { *x = PushSandboxLogsRequest{} - mi := &file_openshell_proto_msgTypes[123] + mi := &file_openshell_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8869,7 +8925,7 @@ func (x *PushSandboxLogsRequest) String() string { func (*PushSandboxLogsRequest) ProtoMessage() {} func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[123] + mi := &file_openshell_proto_msgTypes[124] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8882,7 +8938,7 @@ func (x *PushSandboxLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsRequest.ProtoReflect.Descriptor instead. func (*PushSandboxLogsRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{123} + return file_openshell_proto_rawDescGZIP(), []int{124} } func (x *PushSandboxLogsRequest) GetSandboxId() string { @@ -8908,7 +8964,7 @@ type PushSandboxLogsResponse struct { func (x *PushSandboxLogsResponse) Reset() { *x = PushSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[124] + mi := &file_openshell_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8920,7 +8976,7 @@ func (x *PushSandboxLogsResponse) String() string { func (*PushSandboxLogsResponse) ProtoMessage() {} func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[124] + mi := &file_openshell_proto_msgTypes[125] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8933,7 +8989,7 @@ func (x *PushSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PushSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*PushSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{124} + return file_openshell_proto_rawDescGZIP(), []int{125} } // Get sandbox logs response. @@ -8949,7 +9005,7 @@ type GetSandboxLogsResponse struct { func (x *GetSandboxLogsResponse) Reset() { *x = GetSandboxLogsResponse{} - mi := &file_openshell_proto_msgTypes[125] + mi := &file_openshell_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8961,7 +9017,7 @@ func (x *GetSandboxLogsResponse) String() string { func (*GetSandboxLogsResponse) ProtoMessage() {} func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[125] + mi := &file_openshell_proto_msgTypes[126] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8974,7 +9030,7 @@ func (x *GetSandboxLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetSandboxLogsResponse.ProtoReflect.Descriptor instead. func (*GetSandboxLogsResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{125} + return file_openshell_proto_rawDescGZIP(), []int{126} } func (x *GetSandboxLogsResponse) GetLogs() []*SandboxLogLine { @@ -9007,7 +9063,7 @@ type SupervisorMessage struct { func (x *SupervisorMessage) Reset() { *x = SupervisorMessage{} - mi := &file_openshell_proto_msgTypes[126] + mi := &file_openshell_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9019,7 +9075,7 @@ func (x *SupervisorMessage) String() string { func (*SupervisorMessage) ProtoMessage() {} func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[126] + mi := &file_openshell_proto_msgTypes[127] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9032,7 +9088,7 @@ func (x *SupervisorMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorMessage.ProtoReflect.Descriptor instead. func (*SupervisorMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{126} + return file_openshell_proto_rawDescGZIP(), []int{127} } func (x *SupervisorMessage) GetPayload() isSupervisorMessage_Payload { @@ -9123,7 +9179,7 @@ type GatewayMessage struct { func (x *GatewayMessage) Reset() { *x = GatewayMessage{} - mi := &file_openshell_proto_msgTypes[127] + mi := &file_openshell_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9135,7 +9191,7 @@ func (x *GatewayMessage) String() string { func (*GatewayMessage) ProtoMessage() {} func (x *GatewayMessage) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[127] + mi := &file_openshell_proto_msgTypes[128] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9148,7 +9204,7 @@ func (x *GatewayMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayMessage.ProtoReflect.Descriptor instead. func (*GatewayMessage) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{127} + return file_openshell_proto_rawDescGZIP(), []int{128} } func (x *GatewayMessage) GetPayload() isGatewayMessage_Payload { @@ -9250,7 +9306,7 @@ type SupervisorHello struct { func (x *SupervisorHello) Reset() { *x = SupervisorHello{} - mi := &file_openshell_proto_msgTypes[128] + mi := &file_openshell_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9262,7 +9318,7 @@ func (x *SupervisorHello) String() string { func (*SupervisorHello) ProtoMessage() {} func (x *SupervisorHello) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[128] + mi := &file_openshell_proto_msgTypes[129] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9275,7 +9331,7 @@ func (x *SupervisorHello) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHello.ProtoReflect.Descriptor instead. func (*SupervisorHello) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{128} + return file_openshell_proto_rawDescGZIP(), []int{129} } func (x *SupervisorHello) GetSandboxId() string { @@ -9305,7 +9361,7 @@ type SessionAccepted struct { func (x *SessionAccepted) Reset() { *x = SessionAccepted{} - mi := &file_openshell_proto_msgTypes[129] + mi := &file_openshell_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9317,7 +9373,7 @@ func (x *SessionAccepted) String() string { func (*SessionAccepted) ProtoMessage() {} func (x *SessionAccepted) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[129] + mi := &file_openshell_proto_msgTypes[130] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9330,7 +9386,7 @@ func (x *SessionAccepted) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionAccepted.ProtoReflect.Descriptor instead. func (*SessionAccepted) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{129} + return file_openshell_proto_rawDescGZIP(), []int{130} } func (x *SessionAccepted) GetSessionId() string { @@ -9358,7 +9414,7 @@ type SessionRejected struct { func (x *SessionRejected) Reset() { *x = SessionRejected{} - mi := &file_openshell_proto_msgTypes[130] + mi := &file_openshell_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9370,7 +9426,7 @@ func (x *SessionRejected) String() string { func (*SessionRejected) ProtoMessage() {} func (x *SessionRejected) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[130] + mi := &file_openshell_proto_msgTypes[131] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9383,7 +9439,7 @@ func (x *SessionRejected) ProtoReflect() protoreflect.Message { // Deprecated: Use SessionRejected.ProtoReflect.Descriptor instead. func (*SessionRejected) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{130} + return file_openshell_proto_rawDescGZIP(), []int{131} } func (x *SessionRejected) GetReason() string { @@ -9402,7 +9458,7 @@ type SupervisorHeartbeat struct { func (x *SupervisorHeartbeat) Reset() { *x = SupervisorHeartbeat{} - mi := &file_openshell_proto_msgTypes[131] + mi := &file_openshell_proto_msgTypes[132] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9414,7 +9470,7 @@ func (x *SupervisorHeartbeat) String() string { func (*SupervisorHeartbeat) ProtoMessage() {} func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[131] + mi := &file_openshell_proto_msgTypes[132] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9427,7 +9483,7 @@ func (x *SupervisorHeartbeat) ProtoReflect() protoreflect.Message { // Deprecated: Use SupervisorHeartbeat.ProtoReflect.Descriptor instead. func (*SupervisorHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{131} + return file_openshell_proto_rawDescGZIP(), []int{132} } // Gateway heartbeat. @@ -9439,7 +9495,7 @@ type GatewayHeartbeat struct { func (x *GatewayHeartbeat) Reset() { *x = GatewayHeartbeat{} - mi := &file_openshell_proto_msgTypes[132] + mi := &file_openshell_proto_msgTypes[133] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9451,7 +9507,7 @@ func (x *GatewayHeartbeat) String() string { func (*GatewayHeartbeat) ProtoMessage() {} func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[132] + mi := &file_openshell_proto_msgTypes[133] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9464,7 +9520,7 @@ func (x *GatewayHeartbeat) ProtoReflect() protoreflect.Message { // Deprecated: Use GatewayHeartbeat.ProtoReflect.Descriptor instead. func (*GatewayHeartbeat) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{132} + return file_openshell_proto_rawDescGZIP(), []int{133} } // Gateway requests the supervisor to open a relay channel. @@ -9493,7 +9549,7 @@ type RelayOpen struct { func (x *RelayOpen) Reset() { *x = RelayOpen{} - mi := &file_openshell_proto_msgTypes[133] + mi := &file_openshell_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9505,7 +9561,7 @@ func (x *RelayOpen) String() string { func (*RelayOpen) ProtoMessage() {} func (x *RelayOpen) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[133] + mi := &file_openshell_proto_msgTypes[134] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9518,7 +9574,7 @@ func (x *RelayOpen) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpen.ProtoReflect.Descriptor instead. func (*RelayOpen) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{133} + return file_openshell_proto_rawDescGZIP(), []int{134} } func (x *RelayOpen) GetChannelId() string { @@ -9585,7 +9641,7 @@ type SshRelayTarget struct { func (x *SshRelayTarget) Reset() { *x = SshRelayTarget{} - mi := &file_openshell_proto_msgTypes[134] + mi := &file_openshell_proto_msgTypes[135] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9597,7 +9653,7 @@ func (x *SshRelayTarget) String() string { func (*SshRelayTarget) ProtoMessage() {} func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[134] + mi := &file_openshell_proto_msgTypes[135] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9610,7 +9666,7 @@ func (x *SshRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use SshRelayTarget.ProtoReflect.Descriptor instead. func (*SshRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{134} + return file_openshell_proto_rawDescGZIP(), []int{135} } // TCP target dialed by the supervisor from inside the sandbox. @@ -9626,7 +9682,7 @@ type TcpRelayTarget struct { func (x *TcpRelayTarget) Reset() { *x = TcpRelayTarget{} - mi := &file_openshell_proto_msgTypes[135] + mi := &file_openshell_proto_msgTypes[136] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9638,7 +9694,7 @@ func (x *TcpRelayTarget) String() string { func (*TcpRelayTarget) ProtoMessage() {} func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[135] + mi := &file_openshell_proto_msgTypes[136] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9651,7 +9707,7 @@ func (x *TcpRelayTarget) ProtoReflect() protoreflect.Message { // Deprecated: Use TcpRelayTarget.ProtoReflect.Descriptor instead. func (*TcpRelayTarget) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{135} + return file_openshell_proto_rawDescGZIP(), []int{136} } func (x *TcpRelayTarget) GetHost() string { @@ -9679,7 +9735,7 @@ type RelayInit struct { func (x *RelayInit) Reset() { *x = RelayInit{} - mi := &file_openshell_proto_msgTypes[136] + mi := &file_openshell_proto_msgTypes[137] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9691,7 +9747,7 @@ func (x *RelayInit) String() string { func (*RelayInit) ProtoMessage() {} func (x *RelayInit) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[136] + mi := &file_openshell_proto_msgTypes[137] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9704,7 +9760,7 @@ func (x *RelayInit) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayInit.ProtoReflect.Descriptor instead. func (*RelayInit) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{136} + return file_openshell_proto_rawDescGZIP(), []int{137} } func (x *RelayInit) GetChannelId() string { @@ -9731,7 +9787,7 @@ type RelayFrame struct { func (x *RelayFrame) Reset() { *x = RelayFrame{} - mi := &file_openshell_proto_msgTypes[137] + mi := &file_openshell_proto_msgTypes[138] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9743,7 +9799,7 @@ func (x *RelayFrame) String() string { func (*RelayFrame) ProtoMessage() {} func (x *RelayFrame) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[137] + mi := &file_openshell_proto_msgTypes[138] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9756,7 +9812,7 @@ func (x *RelayFrame) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayFrame.ProtoReflect.Descriptor instead. func (*RelayFrame) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{137} + return file_openshell_proto_rawDescGZIP(), []int{138} } func (x *RelayFrame) GetPayload() isRelayFrame_Payload { @@ -9815,7 +9871,7 @@ type RelayOpenResult struct { func (x *RelayOpenResult) Reset() { *x = RelayOpenResult{} - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[139] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9827,7 +9883,7 @@ func (x *RelayOpenResult) String() string { func (*RelayOpenResult) ProtoMessage() {} func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[138] + mi := &file_openshell_proto_msgTypes[139] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9840,7 +9896,7 @@ func (x *RelayOpenResult) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayOpenResult.ProtoReflect.Descriptor instead. func (*RelayOpenResult) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{138} + return file_openshell_proto_rawDescGZIP(), []int{139} } func (x *RelayOpenResult) GetChannelId() string { @@ -9877,7 +9933,7 @@ type RelayClose struct { func (x *RelayClose) Reset() { *x = RelayClose{} - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[140] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9889,7 +9945,7 @@ func (x *RelayClose) String() string { func (*RelayClose) ProtoMessage() {} func (x *RelayClose) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[139] + mi := &file_openshell_proto_msgTypes[140] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9902,7 +9958,7 @@ func (x *RelayClose) ProtoReflect() protoreflect.Message { // Deprecated: Use RelayClose.ProtoReflect.Descriptor instead. func (*RelayClose) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{139} + return file_openshell_proto_rawDescGZIP(), []int{140} } func (x *RelayClose) GetChannelId() string { @@ -9936,7 +9992,7 @@ type L7RequestSample struct { func (x *L7RequestSample) Reset() { *x = L7RequestSample{} - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[141] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -9948,7 +10004,7 @@ func (x *L7RequestSample) String() string { func (*L7RequestSample) ProtoMessage() {} func (x *L7RequestSample) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[140] + mi := &file_openshell_proto_msgTypes[141] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -9961,7 +10017,7 @@ func (x *L7RequestSample) ProtoReflect() protoreflect.Message { // Deprecated: Use L7RequestSample.ProtoReflect.Descriptor instead. func (*L7RequestSample) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{140} + return file_openshell_proto_rawDescGZIP(), []int{141} } func (x *L7RequestSample) GetMethod() string { @@ -10035,7 +10091,7 @@ type DenialSummary struct { func (x *DenialSummary) Reset() { *x = DenialSummary{} - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10047,7 +10103,7 @@ func (x *DenialSummary) String() string { func (*DenialSummary) ProtoMessage() {} func (x *DenialSummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[141] + mi := &file_openshell_proto_msgTypes[142] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10060,7 +10116,7 @@ func (x *DenialSummary) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialSummary.ProtoReflect.Descriptor instead. func (*DenialSummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{141} + return file_openshell_proto_rawDescGZIP(), []int{142} } func (x *DenialSummary) GetSandboxId() string { @@ -10195,7 +10251,7 @@ type DenialGroupCount struct { func (x *DenialGroupCount) Reset() { *x = DenialGroupCount{} - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[143] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10207,7 +10263,7 @@ func (x *DenialGroupCount) String() string { func (*DenialGroupCount) ProtoMessage() {} func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[142] + mi := &file_openshell_proto_msgTypes[143] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10220,7 +10276,7 @@ func (x *DenialGroupCount) ProtoReflect() protoreflect.Message { // Deprecated: Use DenialGroupCount.ProtoReflect.Descriptor instead. func (*DenialGroupCount) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{142} + return file_openshell_proto_rawDescGZIP(), []int{143} } func (x *DenialGroupCount) GetDenyGroup() string { @@ -10253,7 +10309,7 @@ type NetworkActivitySummary struct { func (x *NetworkActivitySummary) Reset() { *x = NetworkActivitySummary{} - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[144] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10265,7 +10321,7 @@ func (x *NetworkActivitySummary) String() string { func (*NetworkActivitySummary) ProtoMessage() {} func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[143] + mi := &file_openshell_proto_msgTypes[144] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10278,7 +10334,7 @@ func (x *NetworkActivitySummary) ProtoReflect() protoreflect.Message { // Deprecated: Use NetworkActivitySummary.ProtoReflect.Descriptor instead. func (*NetworkActivitySummary) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{143} + return file_openshell_proto_rawDescGZIP(), []int{144} } func (x *NetworkActivitySummary) GetNetworkActivityCount() uint32 { @@ -10352,7 +10408,7 @@ type PolicyChunk struct { func (x *PolicyChunk) Reset() { *x = PolicyChunk{} - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[145] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10364,7 +10420,7 @@ func (x *PolicyChunk) String() string { func (*PolicyChunk) ProtoMessage() {} func (x *PolicyChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[144] + mi := &file_openshell_proto_msgTypes[145] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10377,7 +10433,7 @@ func (x *PolicyChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyChunk.ProtoReflect.Descriptor instead. func (*PolicyChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{144} + return file_openshell_proto_rawDescGZIP(), []int{145} } func (x *PolicyChunk) GetId() string { @@ -10523,7 +10579,7 @@ type DraftPolicyUpdate struct { func (x *DraftPolicyUpdate) Reset() { *x = DraftPolicyUpdate{} - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[146] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10535,7 +10591,7 @@ func (x *DraftPolicyUpdate) String() string { func (*DraftPolicyUpdate) ProtoMessage() {} func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[145] + mi := &file_openshell_proto_msgTypes[146] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10548,7 +10604,7 @@ func (x *DraftPolicyUpdate) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftPolicyUpdate.ProtoReflect.Descriptor instead. func (*DraftPolicyUpdate) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{145} + return file_openshell_proto_rawDescGZIP(), []int{146} } func (x *DraftPolicyUpdate) GetDraftVersion() uint64 { @@ -10606,7 +10662,7 @@ type SubmitPolicyAnalysisRequest struct { func (x *SubmitPolicyAnalysisRequest) Reset() { *x = SubmitPolicyAnalysisRequest{} - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[147] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10618,7 +10674,7 @@ func (x *SubmitPolicyAnalysisRequest) String() string { func (*SubmitPolicyAnalysisRequest) ProtoMessage() {} func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[146] + mi := &file_openshell_proto_msgTypes[147] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10631,7 +10687,7 @@ func (x *SubmitPolicyAnalysisRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisRequest.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{146} + return file_openshell_proto_rawDescGZIP(), []int{147} } func (x *SubmitPolicyAnalysisRequest) GetSummaries() []*DenialSummary { @@ -10694,7 +10750,7 @@ type SubmitPolicyAnalysisResponse struct { func (x *SubmitPolicyAnalysisResponse) Reset() { *x = SubmitPolicyAnalysisResponse{} - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[148] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10706,7 +10762,7 @@ func (x *SubmitPolicyAnalysisResponse) String() string { func (*SubmitPolicyAnalysisResponse) ProtoMessage() {} func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[147] + mi := &file_openshell_proto_msgTypes[148] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10719,7 +10775,7 @@ func (x *SubmitPolicyAnalysisResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SubmitPolicyAnalysisResponse.ProtoReflect.Descriptor instead. func (*SubmitPolicyAnalysisResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{147} + return file_openshell_proto_rawDescGZIP(), []int{148} } func (x *SubmitPolicyAnalysisResponse) GetAcceptedChunks() uint32 { @@ -10765,7 +10821,7 @@ type GetDraftPolicyRequest struct { func (x *GetDraftPolicyRequest) Reset() { *x = GetDraftPolicyRequest{} - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[149] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10777,7 +10833,7 @@ func (x *GetDraftPolicyRequest) String() string { func (*GetDraftPolicyRequest) ProtoMessage() {} func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[148] + mi := &file_openshell_proto_msgTypes[149] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10790,7 +10846,7 @@ func (x *GetDraftPolicyRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyRequest.ProtoReflect.Descriptor instead. func (*GetDraftPolicyRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{148} + return file_openshell_proto_rawDescGZIP(), []int{149} } func (x *GetDraftPolicyRequest) GetName() string { @@ -10830,7 +10886,7 @@ type GetDraftPolicyResponse struct { func (x *GetDraftPolicyResponse) Reset() { *x = GetDraftPolicyResponse{} - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[150] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10842,7 +10898,7 @@ func (x *GetDraftPolicyResponse) String() string { func (*GetDraftPolicyResponse) ProtoMessage() {} func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[149] + mi := &file_openshell_proto_msgTypes[150] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10855,7 +10911,7 @@ func (x *GetDraftPolicyResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftPolicyResponse.ProtoReflect.Descriptor instead. func (*GetDraftPolicyResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{149} + return file_openshell_proto_rawDescGZIP(), []int{150} } func (x *GetDraftPolicyResponse) GetChunks() []*PolicyChunk { @@ -10901,7 +10957,7 @@ type ApproveDraftChunkRequest struct { func (x *ApproveDraftChunkRequest) Reset() { *x = ApproveDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[151] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10913,7 +10969,7 @@ func (x *ApproveDraftChunkRequest) String() string { func (*ApproveDraftChunkRequest) ProtoMessage() {} func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[150] + mi := &file_openshell_proto_msgTypes[151] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10926,7 +10982,7 @@ func (x *ApproveDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkRequest.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{150} + return file_openshell_proto_rawDescGZIP(), []int{151} } func (x *ApproveDraftChunkRequest) GetName() string { @@ -10962,7 +11018,7 @@ type ApproveDraftChunkResponse struct { func (x *ApproveDraftChunkResponse) Reset() { *x = ApproveDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[152] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -10974,7 +11030,7 @@ func (x *ApproveDraftChunkResponse) String() string { func (*ApproveDraftChunkResponse) ProtoMessage() {} func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[151] + mi := &file_openshell_proto_msgTypes[152] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -10987,7 +11043,7 @@ func (x *ApproveDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveDraftChunkResponse.ProtoReflect.Descriptor instead. func (*ApproveDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{151} + return file_openshell_proto_rawDescGZIP(), []int{152} } func (x *ApproveDraftChunkResponse) GetPolicyVersion() uint32 { @@ -11021,7 +11077,7 @@ type RejectDraftChunkRequest struct { func (x *RejectDraftChunkRequest) Reset() { *x = RejectDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[153] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11033,7 +11089,7 @@ func (x *RejectDraftChunkRequest) String() string { func (*RejectDraftChunkRequest) ProtoMessage() {} func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[152] + mi := &file_openshell_proto_msgTypes[153] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11046,7 +11102,7 @@ func (x *RejectDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkRequest.ProtoReflect.Descriptor instead. func (*RejectDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{152} + return file_openshell_proto_rawDescGZIP(), []int{153} } func (x *RejectDraftChunkRequest) GetName() string { @@ -11085,7 +11141,7 @@ type RejectDraftChunkResponse struct { func (x *RejectDraftChunkResponse) Reset() { *x = RejectDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[154] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11097,7 +11153,7 @@ func (x *RejectDraftChunkResponse) String() string { func (*RejectDraftChunkResponse) ProtoMessage() {} func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[153] + mi := &file_openshell_proto_msgTypes[154] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11110,7 +11166,7 @@ func (x *RejectDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RejectDraftChunkResponse.ProtoReflect.Descriptor instead. func (*RejectDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{153} + return file_openshell_proto_rawDescGZIP(), []int{154} } // Approve all pending chunks. @@ -11128,7 +11184,7 @@ type ApproveAllDraftChunksRequest struct { func (x *ApproveAllDraftChunksRequest) Reset() { *x = ApproveAllDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[155] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11140,7 +11196,7 @@ func (x *ApproveAllDraftChunksRequest) String() string { func (*ApproveAllDraftChunksRequest) ProtoMessage() {} func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[154] + mi := &file_openshell_proto_msgTypes[155] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11153,7 +11209,7 @@ func (x *ApproveAllDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{154} + return file_openshell_proto_rawDescGZIP(), []int{155} } func (x *ApproveAllDraftChunksRequest) GetName() string { @@ -11193,7 +11249,7 @@ type ApproveAllDraftChunksResponse struct { func (x *ApproveAllDraftChunksResponse) Reset() { *x = ApproveAllDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[156] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11205,7 +11261,7 @@ func (x *ApproveAllDraftChunksResponse) String() string { func (*ApproveAllDraftChunksResponse) ProtoMessage() {} func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[155] + mi := &file_openshell_proto_msgTypes[156] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11218,7 +11274,7 @@ func (x *ApproveAllDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ApproveAllDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ApproveAllDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{155} + return file_openshell_proto_rawDescGZIP(), []int{156} } func (x *ApproveAllDraftChunksResponse) GetPolicyVersion() uint32 { @@ -11266,7 +11322,7 @@ type EditDraftChunkRequest struct { func (x *EditDraftChunkRequest) Reset() { *x = EditDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[157] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11278,7 +11334,7 @@ func (x *EditDraftChunkRequest) String() string { func (*EditDraftChunkRequest) ProtoMessage() {} func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[156] + mi := &file_openshell_proto_msgTypes[157] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11291,7 +11347,7 @@ func (x *EditDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkRequest.ProtoReflect.Descriptor instead. func (*EditDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{156} + return file_openshell_proto_rawDescGZIP(), []int{157} } func (x *EditDraftChunkRequest) GetName() string { @@ -11330,7 +11386,7 @@ type EditDraftChunkResponse struct { func (x *EditDraftChunkResponse) Reset() { *x = EditDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[158] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11342,7 +11398,7 @@ func (x *EditDraftChunkResponse) String() string { func (*EditDraftChunkResponse) ProtoMessage() {} func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[157] + mi := &file_openshell_proto_msgTypes[158] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11355,7 +11411,7 @@ func (x *EditDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use EditDraftChunkResponse.ProtoReflect.Descriptor instead. func (*EditDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{157} + return file_openshell_proto_rawDescGZIP(), []int{158} } // Reverse an approval (remove merged rule from active policy). @@ -11373,7 +11429,7 @@ type UndoDraftChunkRequest struct { func (x *UndoDraftChunkRequest) Reset() { *x = UndoDraftChunkRequest{} - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[159] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11385,7 +11441,7 @@ func (x *UndoDraftChunkRequest) String() string { func (*UndoDraftChunkRequest) ProtoMessage() {} func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[158] + mi := &file_openshell_proto_msgTypes[159] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11398,7 +11454,7 @@ func (x *UndoDraftChunkRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkRequest.ProtoReflect.Descriptor instead. func (*UndoDraftChunkRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{158} + return file_openshell_proto_rawDescGZIP(), []int{159} } func (x *UndoDraftChunkRequest) GetName() string { @@ -11434,7 +11490,7 @@ type UndoDraftChunkResponse struct { func (x *UndoDraftChunkResponse) Reset() { *x = UndoDraftChunkResponse{} - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[160] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11446,7 +11502,7 @@ func (x *UndoDraftChunkResponse) String() string { func (*UndoDraftChunkResponse) ProtoMessage() {} func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[159] + mi := &file_openshell_proto_msgTypes[160] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11459,7 +11515,7 @@ func (x *UndoDraftChunkResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UndoDraftChunkResponse.ProtoReflect.Descriptor instead. func (*UndoDraftChunkResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{159} + return file_openshell_proto_rawDescGZIP(), []int{160} } func (x *UndoDraftChunkResponse) GetPolicyVersion() uint32 { @@ -11489,7 +11545,7 @@ type ClearDraftChunksRequest struct { func (x *ClearDraftChunksRequest) Reset() { *x = ClearDraftChunksRequest{} - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[161] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11501,7 +11557,7 @@ func (x *ClearDraftChunksRequest) String() string { func (*ClearDraftChunksRequest) ProtoMessage() {} func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[160] + mi := &file_openshell_proto_msgTypes[161] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11514,7 +11570,7 @@ func (x *ClearDraftChunksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksRequest.ProtoReflect.Descriptor instead. func (*ClearDraftChunksRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{160} + return file_openshell_proto_rawDescGZIP(), []int{161} } func (x *ClearDraftChunksRequest) GetName() string { @@ -11541,7 +11597,7 @@ type ClearDraftChunksResponse struct { func (x *ClearDraftChunksResponse) Reset() { *x = ClearDraftChunksResponse{} - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[162] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11553,7 +11609,7 @@ func (x *ClearDraftChunksResponse) String() string { func (*ClearDraftChunksResponse) ProtoMessage() {} func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[161] + mi := &file_openshell_proto_msgTypes[162] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11566,7 +11622,7 @@ func (x *ClearDraftChunksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ClearDraftChunksResponse.ProtoReflect.Descriptor instead. func (*ClearDraftChunksResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{161} + return file_openshell_proto_rawDescGZIP(), []int{162} } func (x *ClearDraftChunksResponse) GetChunksCleared() uint32 { @@ -11589,7 +11645,7 @@ type GetDraftHistoryRequest struct { func (x *GetDraftHistoryRequest) Reset() { *x = GetDraftHistoryRequest{} - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[163] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11601,7 +11657,7 @@ func (x *GetDraftHistoryRequest) String() string { func (*GetDraftHistoryRequest) ProtoMessage() {} func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[162] + mi := &file_openshell_proto_msgTypes[163] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11614,7 +11670,7 @@ func (x *GetDraftHistoryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryRequest.ProtoReflect.Descriptor instead. func (*GetDraftHistoryRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{162} + return file_openshell_proto_rawDescGZIP(), []int{163} } func (x *GetDraftHistoryRequest) GetName() string { @@ -11648,7 +11704,7 @@ type DraftHistoryEntry struct { func (x *DraftHistoryEntry) Reset() { *x = DraftHistoryEntry{} - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[164] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11660,7 +11716,7 @@ func (x *DraftHistoryEntry) String() string { func (*DraftHistoryEntry) ProtoMessage() {} func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[163] + mi := &file_openshell_proto_msgTypes[164] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11673,7 +11729,7 @@ func (x *DraftHistoryEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftHistoryEntry.ProtoReflect.Descriptor instead. func (*DraftHistoryEntry) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{163} + return file_openshell_proto_rawDescGZIP(), []int{164} } func (x *DraftHistoryEntry) GetTimestampMs() int64 { @@ -11714,7 +11770,7 @@ type GetDraftHistoryResponse struct { func (x *GetDraftHistoryResponse) Reset() { *x = GetDraftHistoryResponse{} - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[165] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11726,7 +11782,7 @@ func (x *GetDraftHistoryResponse) String() string { func (*GetDraftHistoryResponse) ProtoMessage() {} func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[164] + mi := &file_openshell_proto_msgTypes[165] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11739,7 +11795,7 @@ func (x *GetDraftHistoryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetDraftHistoryResponse.ProtoReflect.Descriptor instead. func (*GetDraftHistoryResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{164} + return file_openshell_proto_rawDescGZIP(), []int{165} } func (x *GetDraftHistoryResponse) GetEntries() []*DraftHistoryEntry { @@ -11768,7 +11824,7 @@ type PolicyRevisionPayload struct { func (x *PolicyRevisionPayload) Reset() { *x = PolicyRevisionPayload{} - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[166] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11780,7 +11836,7 @@ func (x *PolicyRevisionPayload) String() string { func (*PolicyRevisionPayload) ProtoMessage() {} func (x *PolicyRevisionPayload) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[165] + mi := &file_openshell_proto_msgTypes[166] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11793,7 +11849,7 @@ func (x *PolicyRevisionPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use PolicyRevisionPayload.ProtoReflect.Descriptor instead. func (*PolicyRevisionPayload) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{165} + return file_openshell_proto_rawDescGZIP(), []int{166} } func (x *PolicyRevisionPayload) GetPolicy() *sandboxv1.SandboxPolicy { @@ -11866,7 +11922,7 @@ type DraftChunkPayload struct { func (x *DraftChunkPayload) Reset() { *x = DraftChunkPayload{} - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[167] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -11878,7 +11934,7 @@ func (x *DraftChunkPayload) String() string { func (*DraftChunkPayload) ProtoMessage() {} func (x *DraftChunkPayload) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[166] + mi := &file_openshell_proto_msgTypes[167] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -11891,7 +11947,7 @@ func (x *DraftChunkPayload) ProtoReflect() protoreflect.Message { // Deprecated: Use DraftChunkPayload.ProtoReflect.Descriptor instead. func (*DraftChunkPayload) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{166} + return file_openshell_proto_rawDescGZIP(), []int{167} } func (x *DraftChunkPayload) GetRuleName() string { @@ -11997,7 +12053,7 @@ type StoredPolicyRevision struct { func (x *StoredPolicyRevision) Reset() { *x = StoredPolicyRevision{} - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[168] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12009,7 +12065,7 @@ func (x *StoredPolicyRevision) String() string { func (*StoredPolicyRevision) ProtoMessage() {} func (x *StoredPolicyRevision) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[167] + mi := &file_openshell_proto_msgTypes[168] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12022,7 +12078,7 @@ func (x *StoredPolicyRevision) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredPolicyRevision.ProtoReflect.Descriptor instead. func (*StoredPolicyRevision) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{167} + return file_openshell_proto_rawDescGZIP(), []int{168} } func (x *StoredPolicyRevision) GetId() string { @@ -12125,7 +12181,7 @@ type StoredDraftChunk struct { func (x *StoredDraftChunk) Reset() { *x = StoredDraftChunk{} - mi := &file_openshell_proto_msgTypes[168] + mi := &file_openshell_proto_msgTypes[169] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12137,7 +12193,7 @@ func (x *StoredDraftChunk) String() string { func (*StoredDraftChunk) ProtoMessage() {} func (x *StoredDraftChunk) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[168] + mi := &file_openshell_proto_msgTypes[169] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12150,7 +12206,7 @@ func (x *StoredDraftChunk) ProtoReflect() protoreflect.Message { // Deprecated: Use StoredDraftChunk.ProtoReflect.Descriptor instead. func (*StoredDraftChunk) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{168} + return file_openshell_proto_rawDescGZIP(), []int{169} } func (x *StoredDraftChunk) GetId() string { @@ -12299,7 +12355,7 @@ type CreateWorkspaceRequest struct { func (x *CreateWorkspaceRequest) Reset() { *x = CreateWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[169] + mi := &file_openshell_proto_msgTypes[170] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12311,7 +12367,7 @@ func (x *CreateWorkspaceRequest) String() string { func (*CreateWorkspaceRequest) ProtoMessage() {} func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[169] + mi := &file_openshell_proto_msgTypes[170] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12324,7 +12380,7 @@ func (x *CreateWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceRequest.ProtoReflect.Descriptor instead. func (*CreateWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{169} + return file_openshell_proto_rawDescGZIP(), []int{170} } func (x *CreateWorkspaceRequest) GetName() string { @@ -12351,7 +12407,7 @@ type CreateWorkspaceResponse struct { func (x *CreateWorkspaceResponse) Reset() { *x = CreateWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[170] + mi := &file_openshell_proto_msgTypes[171] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12363,7 +12419,7 @@ func (x *CreateWorkspaceResponse) String() string { func (*CreateWorkspaceResponse) ProtoMessage() {} func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[170] + mi := &file_openshell_proto_msgTypes[171] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12376,7 +12432,7 @@ func (x *CreateWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateWorkspaceResponse.ProtoReflect.Descriptor instead. func (*CreateWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{170} + return file_openshell_proto_rawDescGZIP(), []int{171} } func (x *CreateWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -12397,7 +12453,7 @@ type GetWorkspaceRequest struct { func (x *GetWorkspaceRequest) Reset() { *x = GetWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[172] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12409,7 +12465,7 @@ func (x *GetWorkspaceRequest) String() string { func (*GetWorkspaceRequest) ProtoMessage() {} func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[171] + mi := &file_openshell_proto_msgTypes[172] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12422,7 +12478,7 @@ func (x *GetWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceRequest.ProtoReflect.Descriptor instead. func (*GetWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{171} + return file_openshell_proto_rawDescGZIP(), []int{172} } func (x *GetWorkspaceRequest) GetName() string { @@ -12442,7 +12498,7 @@ type GetWorkspaceResponse struct { func (x *GetWorkspaceResponse) Reset() { *x = GetWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[173] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12454,7 +12510,7 @@ func (x *GetWorkspaceResponse) String() string { func (*GetWorkspaceResponse) ProtoMessage() {} func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[172] + mi := &file_openshell_proto_msgTypes[173] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12467,7 +12523,7 @@ func (x *GetWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetWorkspaceResponse.ProtoReflect.Descriptor instead. func (*GetWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{172} + return file_openshell_proto_rawDescGZIP(), []int{173} } func (x *GetWorkspaceResponse) GetWorkspace() *datamodelv1.Workspace { @@ -12490,7 +12546,7 @@ type ListWorkspacesRequest struct { func (x *ListWorkspacesRequest) Reset() { *x = ListWorkspacesRequest{} - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[174] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12502,7 +12558,7 @@ func (x *ListWorkspacesRequest) String() string { func (*ListWorkspacesRequest) ProtoMessage() {} func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[173] + mi := &file_openshell_proto_msgTypes[174] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12515,7 +12571,7 @@ func (x *ListWorkspacesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesRequest.ProtoReflect.Descriptor instead. func (*ListWorkspacesRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{173} + return file_openshell_proto_rawDescGZIP(), []int{174} } func (x *ListWorkspacesRequest) GetLimit() uint32 { @@ -12549,7 +12605,7 @@ type ListWorkspacesResponse struct { func (x *ListWorkspacesResponse) Reset() { *x = ListWorkspacesResponse{} - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[175] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12561,7 +12617,7 @@ func (x *ListWorkspacesResponse) String() string { func (*ListWorkspacesResponse) ProtoMessage() {} func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[174] + mi := &file_openshell_proto_msgTypes[175] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12574,7 +12630,7 @@ func (x *ListWorkspacesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspacesResponse.ProtoReflect.Descriptor instead. func (*ListWorkspacesResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{174} + return file_openshell_proto_rawDescGZIP(), []int{175} } func (x *ListWorkspacesResponse) GetWorkspaces() []*datamodelv1.Workspace { @@ -12595,7 +12651,7 @@ type DeleteWorkspaceRequest struct { func (x *DeleteWorkspaceRequest) Reset() { *x = DeleteWorkspaceRequest{} - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[176] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12607,7 +12663,7 @@ func (x *DeleteWorkspaceRequest) String() string { func (*DeleteWorkspaceRequest) ProtoMessage() {} func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[175] + mi := &file_openshell_proto_msgTypes[176] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12620,7 +12676,7 @@ func (x *DeleteWorkspaceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceRequest.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{175} + return file_openshell_proto_rawDescGZIP(), []int{176} } func (x *DeleteWorkspaceRequest) GetName() string { @@ -12640,7 +12696,7 @@ type DeleteWorkspaceResponse struct { func (x *DeleteWorkspaceResponse) Reset() { *x = DeleteWorkspaceResponse{} - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[177] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12652,7 +12708,7 @@ func (x *DeleteWorkspaceResponse) String() string { func (*DeleteWorkspaceResponse) ProtoMessage() {} func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[176] + mi := &file_openshell_proto_msgTypes[177] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12665,7 +12721,7 @@ func (x *DeleteWorkspaceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteWorkspaceResponse.ProtoReflect.Descriptor instead. func (*DeleteWorkspaceResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{176} + return file_openshell_proto_rawDescGZIP(), []int{177} } func (x *DeleteWorkspaceResponse) GetDeleted() bool { @@ -12689,7 +12745,7 @@ type WorkspaceMember struct { func (x *WorkspaceMember) Reset() { *x = WorkspaceMember{} - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[178] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12701,7 +12757,7 @@ func (x *WorkspaceMember) String() string { func (*WorkspaceMember) ProtoMessage() {} func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[177] + mi := &file_openshell_proto_msgTypes[178] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12714,7 +12770,7 @@ func (x *WorkspaceMember) ProtoReflect() protoreflect.Message { // Deprecated: Use WorkspaceMember.ProtoReflect.Descriptor instead. func (*WorkspaceMember) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{177} + return file_openshell_proto_rawDescGZIP(), []int{178} } func (x *WorkspaceMember) GetMetadata() *datamodelv1.ObjectMeta { @@ -12753,7 +12809,7 @@ type AddWorkspaceMemberRequest struct { func (x *AddWorkspaceMemberRequest) Reset() { *x = AddWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[179] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12765,7 +12821,7 @@ func (x *AddWorkspaceMemberRequest) String() string { func (*AddWorkspaceMemberRequest) ProtoMessage() {} func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[178] + mi := &file_openshell_proto_msgTypes[179] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12778,7 +12834,7 @@ func (x *AddWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{178} + return file_openshell_proto_rawDescGZIP(), []int{179} } func (x *AddWorkspaceMemberRequest) GetWorkspace() string { @@ -12812,7 +12868,7 @@ type AddWorkspaceMemberResponse struct { func (x *AddWorkspaceMemberResponse) Reset() { *x = AddWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[180] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12824,7 +12880,7 @@ func (x *AddWorkspaceMemberResponse) String() string { func (*AddWorkspaceMemberResponse) ProtoMessage() {} func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[179] + mi := &file_openshell_proto_msgTypes[180] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12837,7 +12893,7 @@ func (x *AddWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*AddWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{179} + return file_openshell_proto_rawDescGZIP(), []int{180} } func (x *AddWorkspaceMemberResponse) GetMember() *WorkspaceMember { @@ -12860,7 +12916,7 @@ type RemoveWorkspaceMemberRequest struct { func (x *RemoveWorkspaceMemberRequest) Reset() { *x = RemoveWorkspaceMemberRequest{} - mi := &file_openshell_proto_msgTypes[180] + mi := &file_openshell_proto_msgTypes[181] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12872,7 +12928,7 @@ func (x *RemoveWorkspaceMemberRequest) String() string { func (*RemoveWorkspaceMemberRequest) ProtoMessage() {} func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[180] + mi := &file_openshell_proto_msgTypes[181] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12885,7 +12941,7 @@ func (x *RemoveWorkspaceMemberRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberRequest.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{180} + return file_openshell_proto_rawDescGZIP(), []int{181} } func (x *RemoveWorkspaceMemberRequest) GetWorkspace() string { @@ -12912,7 +12968,7 @@ type RemoveWorkspaceMemberResponse struct { func (x *RemoveWorkspaceMemberResponse) Reset() { *x = RemoveWorkspaceMemberResponse{} - mi := &file_openshell_proto_msgTypes[181] + mi := &file_openshell_proto_msgTypes[182] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12924,7 +12980,7 @@ func (x *RemoveWorkspaceMemberResponse) String() string { func (*RemoveWorkspaceMemberResponse) ProtoMessage() {} func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[181] + mi := &file_openshell_proto_msgTypes[182] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12937,7 +12993,7 @@ func (x *RemoveWorkspaceMemberResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveWorkspaceMemberResponse.ProtoReflect.Descriptor instead. func (*RemoveWorkspaceMemberResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{181} + return file_openshell_proto_rawDescGZIP(), []int{182} } func (x *RemoveWorkspaceMemberResponse) GetRemoved() bool { @@ -12960,7 +13016,7 @@ type ListWorkspaceMembersRequest struct { func (x *ListWorkspaceMembersRequest) Reset() { *x = ListWorkspaceMembersRequest{} - mi := &file_openshell_proto_msgTypes[182] + mi := &file_openshell_proto_msgTypes[183] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -12972,7 +13028,7 @@ func (x *ListWorkspaceMembersRequest) String() string { func (*ListWorkspaceMembersRequest) ProtoMessage() {} func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[182] + mi := &file_openshell_proto_msgTypes[183] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -12985,7 +13041,7 @@ func (x *ListWorkspaceMembersRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersRequest.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersRequest) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{182} + return file_openshell_proto_rawDescGZIP(), []int{183} } func (x *ListWorkspaceMembersRequest) GetWorkspace() string { @@ -13019,7 +13075,7 @@ type ListWorkspaceMembersResponse struct { func (x *ListWorkspaceMembersResponse) Reset() { *x = ListWorkspaceMembersResponse{} - mi := &file_openshell_proto_msgTypes[183] + mi := &file_openshell_proto_msgTypes[184] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13031,7 +13087,7 @@ func (x *ListWorkspaceMembersResponse) String() string { func (*ListWorkspaceMembersResponse) ProtoMessage() {} func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[183] + mi := &file_openshell_proto_msgTypes[184] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13044,7 +13100,7 @@ func (x *ListWorkspaceMembersResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListWorkspaceMembersResponse.ProtoReflect.Descriptor instead. func (*ListWorkspaceMembersResponse) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{183} + return file_openshell_proto_rawDescGZIP(), []int{184} } func (x *ListWorkspaceMembersResponse) GetMembers() []*WorkspaceMember { @@ -13072,7 +13128,7 @@ type ExtensionServiceCredential struct { func (x *ExtensionServiceCredential) Reset() { *x = ExtensionServiceCredential{} - mi := &file_openshell_proto_msgTypes[184] + mi := &file_openshell_proto_msgTypes[185] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -13084,7 +13140,7 @@ func (x *ExtensionServiceCredential) String() string { func (*ExtensionServiceCredential) ProtoMessage() {} func (x *ExtensionServiceCredential) ProtoReflect() protoreflect.Message { - mi := &file_openshell_proto_msgTypes[184] + mi := &file_openshell_proto_msgTypes[185] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -13097,7 +13153,7 @@ func (x *ExtensionServiceCredential) ProtoReflect() protoreflect.Message { // Deprecated: Use ExtensionServiceCredential.ProtoReflect.Descriptor instead. func (*ExtensionServiceCredential) Descriptor() ([]byte, []int) { - return file_openshell_proto_rawDescGZIP(), []int{184} + return file_openshell_proto_rawDescGZIP(), []int{185} } func (x *ExtensionServiceCredential) GetServiceName() string { @@ -13533,7 +13589,7 @@ const file_openshell_proto_rawDesc = "" + "\n" + "last_error\x18\t \x01(\tR\tlastError\"<\n" + "\x18ProviderProfileDiscovery\x12 \n" + - "\vcredentials\x18\x01 \x03(\tR\vcredentials\"\xc0\f\n" + + "\vcredentials\x18\x01 \x03(\tR\vcredentials\"\xa7\v\n" + "$StoredProviderCredentialRefreshState\x12>\n" + "\bmetadata\x18\x01 \x01(\v2\".openshell.datamodel.v1.ObjectMetaR\bmetadata\x12\x1f\n" + "\vprovider_id\x18\x02 \x01(\tR\n" + @@ -13556,8 +13612,8 @@ const file_openshell_proto_rawDesc = "" + "\x14max_lifetime_seconds\x18\x10 \x01(\x03R\x12maxLifetimeSeconds\x12\x82\x01\n" + "\x16additional_output_keys\x18\x11 \x03(\v2L.openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntryR\x14additionalOutputKeys\x12/\n" + "\x13authorization_epoch\x18\x12 \x01(\tR\x12authorizationEpoch\x12\x85\x01\n" + - "\x17secret_material_handles\x18\x13 \x03(\v2M.openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntryR\x15secretMaterialHandles\x12\x88\x01\n" + - "\x18pending_secret_deletions\x18\x14 \x03(\v2N.openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntryR\x16pendingSecretDeletions\x1a;\n" + + "\x17secret_material_handles\x18\x13 \x03(\v2M.openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntryR\x15secretMaterialHandles\x12e\n" + + "\x18pending_secret_deletions\x18\x14 \x03(\v2+.openshell.v1.StoredRefreshMaterialDeletionR\x16pendingSecretDeletions\x1a;\n" + "\rMaterialEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1aG\n" + @@ -13566,10 +13622,10 @@ const file_openshell_proto_rawDesc = "" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1ar\n" + "\x1aSecretMaterialHandlesEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12>\n" + - "\x05value\x18\x02 \x01(\v2(.openshell.datamodel.v1.CredentialHandleR\x05value:\x028\x01\x1as\n" + - "\x1bPendingSecretDeletionsEntry\x12\x10\n" + - "\x03key\x18\x01 \x01(\tR\x03key\x12>\n" + - "\x05value\x18\x02 \x01(\v2(.openshell.datamodel.v1.CredentialHandleR\x05value:\x028\x01\"\x82\x01\n" + + "\x05value\x18\x02 \x01(\v2(.openshell.datamodel.v1.CredentialHandleR\x05value:\x028\x01\"\x84\x01\n" + + "\x1dStoredRefreshMaterialDeletion\x12!\n" + + "\fmaterial_key\x18\x01 \x01(\tR\vmaterialKey\x12@\n" + + "\x06handle\x18\x02 \x01(\v2(.openshell.datamodel.v1.CredentialHandleR\x06handle\"\x82\x01\n" + "\x1fGetProviderRefreshStatusRequest\x12\x1a\n" + "\bprovider\x18\x01 \x01(\tR\bprovider\x12%\n" + "\x0ecredential_key\x18\x02 \x01(\tR\rcredentialKey\x12\x1c\n" + @@ -14410,124 +14466,124 @@ var file_openshell_proto_goTypes = []any{ (*ProviderCredentialRefreshStatus)(nil), // 84: openshell.v1.ProviderCredentialRefreshStatus (*ProviderProfileDiscovery)(nil), // 85: openshell.v1.ProviderProfileDiscovery (*StoredProviderCredentialRefreshState)(nil), // 86: openshell.v1.StoredProviderCredentialRefreshState - (*GetProviderRefreshStatusRequest)(nil), // 87: openshell.v1.GetProviderRefreshStatusRequest - (*GetProviderRefreshStatusResponse)(nil), // 88: openshell.v1.GetProviderRefreshStatusResponse - (*ConfigureProviderRefreshRequest)(nil), // 89: openshell.v1.ConfigureProviderRefreshRequest - (*ConfigureProviderRefreshResponse)(nil), // 90: openshell.v1.ConfigureProviderRefreshResponse - (*RotateProviderCredentialRequest)(nil), // 91: openshell.v1.RotateProviderCredentialRequest - (*RotateProviderCredentialResponse)(nil), // 92: openshell.v1.RotateProviderCredentialResponse - (*DeleteProviderRefreshRequest)(nil), // 93: openshell.v1.DeleteProviderRefreshRequest - (*DeleteProviderRefreshResponse)(nil), // 94: openshell.v1.DeleteProviderRefreshResponse - (*ProviderProfile)(nil), // 95: openshell.v1.ProviderProfile - (*StoredProviderProfile)(nil), // 96: openshell.v1.StoredProviderProfile - (*ProviderProfileResponse)(nil), // 97: openshell.v1.ProviderProfileResponse - (*ListProviderProfilesResponse)(nil), // 98: openshell.v1.ListProviderProfilesResponse - (*ImportProviderProfilesRequest)(nil), // 99: openshell.v1.ImportProviderProfilesRequest - (*ImportProviderProfilesResponse)(nil), // 100: openshell.v1.ImportProviderProfilesResponse - (*UpdateProviderProfilesRequest)(nil), // 101: openshell.v1.UpdateProviderProfilesRequest - (*UpdateProviderProfilesResponse)(nil), // 102: openshell.v1.UpdateProviderProfilesResponse - (*LintProviderProfilesRequest)(nil), // 103: openshell.v1.LintProviderProfilesRequest - (*LintProviderProfilesResponse)(nil), // 104: openshell.v1.LintProviderProfilesResponse - (*DeleteProviderResponse)(nil), // 105: openshell.v1.DeleteProviderResponse - (*DeleteProviderProfileRequest)(nil), // 106: openshell.v1.DeleteProviderProfileRequest - (*DeleteProviderProfileResponse)(nil), // 107: openshell.v1.DeleteProviderProfileResponse - (*GetSandboxProviderEnvironmentRequest)(nil), // 108: openshell.v1.GetSandboxProviderEnvironmentRequest - (*StaticCredentialEndpointBinding)(nil), // 109: openshell.v1.StaticCredentialEndpointBinding - (*StaticCredentialBinding)(nil), // 110: openshell.v1.StaticCredentialBinding - (*GetSandboxProviderEnvironmentResponse)(nil), // 111: openshell.v1.GetSandboxProviderEnvironmentResponse - (*UpdateConfigRequest)(nil), // 112: openshell.v1.UpdateConfigRequest - (*PolicyMergeOperation)(nil), // 113: openshell.v1.PolicyMergeOperation - (*AddNetworkRule)(nil), // 114: openshell.v1.AddNetworkRule - (*RemoveNetworkEndpoint)(nil), // 115: openshell.v1.RemoveNetworkEndpoint - (*RemoveNetworkRule)(nil), // 116: openshell.v1.RemoveNetworkRule - (*AddDenyRules)(nil), // 117: openshell.v1.AddDenyRules - (*AddAllowRules)(nil), // 118: openshell.v1.AddAllowRules - (*RemoveNetworkBinary)(nil), // 119: openshell.v1.RemoveNetworkBinary - (*UpdateConfigResponse)(nil), // 120: openshell.v1.UpdateConfigResponse - (*GetSandboxPolicyStatusRequest)(nil), // 121: openshell.v1.GetSandboxPolicyStatusRequest - (*GetSandboxPolicyStatusResponse)(nil), // 122: openshell.v1.GetSandboxPolicyStatusResponse - (*ListSandboxPoliciesRequest)(nil), // 123: openshell.v1.ListSandboxPoliciesRequest - (*ListSandboxPoliciesResponse)(nil), // 124: openshell.v1.ListSandboxPoliciesResponse - (*ReportPolicyStatusRequest)(nil), // 125: openshell.v1.ReportPolicyStatusRequest - (*ReportPolicyStatusResponse)(nil), // 126: openshell.v1.ReportPolicyStatusResponse - (*SandboxPolicyRevision)(nil), // 127: openshell.v1.SandboxPolicyRevision - (*GetSandboxLogsRequest)(nil), // 128: openshell.v1.GetSandboxLogsRequest - (*PushSandboxLogsRequest)(nil), // 129: openshell.v1.PushSandboxLogsRequest - (*PushSandboxLogsResponse)(nil), // 130: openshell.v1.PushSandboxLogsResponse - (*GetSandboxLogsResponse)(nil), // 131: openshell.v1.GetSandboxLogsResponse - (*SupervisorMessage)(nil), // 132: openshell.v1.SupervisorMessage - (*GatewayMessage)(nil), // 133: openshell.v1.GatewayMessage - (*SupervisorHello)(nil), // 134: openshell.v1.SupervisorHello - (*SessionAccepted)(nil), // 135: openshell.v1.SessionAccepted - (*SessionRejected)(nil), // 136: openshell.v1.SessionRejected - (*SupervisorHeartbeat)(nil), // 137: openshell.v1.SupervisorHeartbeat - (*GatewayHeartbeat)(nil), // 138: openshell.v1.GatewayHeartbeat - (*RelayOpen)(nil), // 139: openshell.v1.RelayOpen - (*SshRelayTarget)(nil), // 140: openshell.v1.SshRelayTarget - (*TcpRelayTarget)(nil), // 141: openshell.v1.TcpRelayTarget - (*RelayInit)(nil), // 142: openshell.v1.RelayInit - (*RelayFrame)(nil), // 143: openshell.v1.RelayFrame - (*RelayOpenResult)(nil), // 144: openshell.v1.RelayOpenResult - (*RelayClose)(nil), // 145: openshell.v1.RelayClose - (*L7RequestSample)(nil), // 146: openshell.v1.L7RequestSample - (*DenialSummary)(nil), // 147: openshell.v1.DenialSummary - (*DenialGroupCount)(nil), // 148: openshell.v1.DenialGroupCount - (*NetworkActivitySummary)(nil), // 149: openshell.v1.NetworkActivitySummary - (*PolicyChunk)(nil), // 150: openshell.v1.PolicyChunk - (*DraftPolicyUpdate)(nil), // 151: openshell.v1.DraftPolicyUpdate - (*SubmitPolicyAnalysisRequest)(nil), // 152: openshell.v1.SubmitPolicyAnalysisRequest - (*SubmitPolicyAnalysisResponse)(nil), // 153: openshell.v1.SubmitPolicyAnalysisResponse - (*GetDraftPolicyRequest)(nil), // 154: openshell.v1.GetDraftPolicyRequest - (*GetDraftPolicyResponse)(nil), // 155: openshell.v1.GetDraftPolicyResponse - (*ApproveDraftChunkRequest)(nil), // 156: openshell.v1.ApproveDraftChunkRequest - (*ApproveDraftChunkResponse)(nil), // 157: openshell.v1.ApproveDraftChunkResponse - (*RejectDraftChunkRequest)(nil), // 158: openshell.v1.RejectDraftChunkRequest - (*RejectDraftChunkResponse)(nil), // 159: openshell.v1.RejectDraftChunkResponse - (*ApproveAllDraftChunksRequest)(nil), // 160: openshell.v1.ApproveAllDraftChunksRequest - (*ApproveAllDraftChunksResponse)(nil), // 161: openshell.v1.ApproveAllDraftChunksResponse - (*EditDraftChunkRequest)(nil), // 162: openshell.v1.EditDraftChunkRequest - (*EditDraftChunkResponse)(nil), // 163: openshell.v1.EditDraftChunkResponse - (*UndoDraftChunkRequest)(nil), // 164: openshell.v1.UndoDraftChunkRequest - (*UndoDraftChunkResponse)(nil), // 165: openshell.v1.UndoDraftChunkResponse - (*ClearDraftChunksRequest)(nil), // 166: openshell.v1.ClearDraftChunksRequest - (*ClearDraftChunksResponse)(nil), // 167: openshell.v1.ClearDraftChunksResponse - (*GetDraftHistoryRequest)(nil), // 168: openshell.v1.GetDraftHistoryRequest - (*DraftHistoryEntry)(nil), // 169: openshell.v1.DraftHistoryEntry - (*GetDraftHistoryResponse)(nil), // 170: openshell.v1.GetDraftHistoryResponse - (*PolicyRevisionPayload)(nil), // 171: openshell.v1.PolicyRevisionPayload - (*DraftChunkPayload)(nil), // 172: openshell.v1.DraftChunkPayload - (*StoredPolicyRevision)(nil), // 173: openshell.v1.StoredPolicyRevision - (*StoredDraftChunk)(nil), // 174: openshell.v1.StoredDraftChunk - (*CreateWorkspaceRequest)(nil), // 175: openshell.v1.CreateWorkspaceRequest - (*CreateWorkspaceResponse)(nil), // 176: openshell.v1.CreateWorkspaceResponse - (*GetWorkspaceRequest)(nil), // 177: openshell.v1.GetWorkspaceRequest - (*GetWorkspaceResponse)(nil), // 178: openshell.v1.GetWorkspaceResponse - (*ListWorkspacesRequest)(nil), // 179: openshell.v1.ListWorkspacesRequest - (*ListWorkspacesResponse)(nil), // 180: openshell.v1.ListWorkspacesResponse - (*DeleteWorkspaceRequest)(nil), // 181: openshell.v1.DeleteWorkspaceRequest - (*DeleteWorkspaceResponse)(nil), // 182: openshell.v1.DeleteWorkspaceResponse - (*WorkspaceMember)(nil), // 183: openshell.v1.WorkspaceMember - (*AddWorkspaceMemberRequest)(nil), // 184: openshell.v1.AddWorkspaceMemberRequest - (*AddWorkspaceMemberResponse)(nil), // 185: openshell.v1.AddWorkspaceMemberResponse - (*RemoveWorkspaceMemberRequest)(nil), // 186: openshell.v1.RemoveWorkspaceMemberRequest - (*RemoveWorkspaceMemberResponse)(nil), // 187: openshell.v1.RemoveWorkspaceMemberResponse - (*ListWorkspaceMembersRequest)(nil), // 188: openshell.v1.ListWorkspaceMembersRequest - (*ListWorkspaceMembersResponse)(nil), // 189: openshell.v1.ListWorkspaceMembersResponse - (*ExtensionServiceCredential)(nil), // 190: openshell.v1.ExtensionServiceCredential - nil, // 191: openshell.v1.SandboxSpec.EnvironmentEntry - nil, // 192: openshell.v1.SandboxTemplate.LabelsEntry - nil, // 193: openshell.v1.SandboxTemplate.AnnotationsEntry - nil, // 194: openshell.v1.SandboxTemplate.EnvironmentEntry - nil, // 195: openshell.v1.PlatformEvent.MetadataEntry - nil, // 196: openshell.v1.CreateSandboxRequest.LabelsEntry - nil, // 197: openshell.v1.CreateSandboxRequest.AnnotationsEntry - nil, // 198: openshell.v1.ExecSandboxRequest.EnvironmentEntry - nil, // 199: openshell.v1.SandboxLogLine.FieldsEntry - nil, // 200: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry - nil, // 201: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry - nil, // 202: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - nil, // 203: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry - nil, // 204: openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntry + (*StoredRefreshMaterialDeletion)(nil), // 87: openshell.v1.StoredRefreshMaterialDeletion + (*GetProviderRefreshStatusRequest)(nil), // 88: openshell.v1.GetProviderRefreshStatusRequest + (*GetProviderRefreshStatusResponse)(nil), // 89: openshell.v1.GetProviderRefreshStatusResponse + (*ConfigureProviderRefreshRequest)(nil), // 90: openshell.v1.ConfigureProviderRefreshRequest + (*ConfigureProviderRefreshResponse)(nil), // 91: openshell.v1.ConfigureProviderRefreshResponse + (*RotateProviderCredentialRequest)(nil), // 92: openshell.v1.RotateProviderCredentialRequest + (*RotateProviderCredentialResponse)(nil), // 93: openshell.v1.RotateProviderCredentialResponse + (*DeleteProviderRefreshRequest)(nil), // 94: openshell.v1.DeleteProviderRefreshRequest + (*DeleteProviderRefreshResponse)(nil), // 95: openshell.v1.DeleteProviderRefreshResponse + (*ProviderProfile)(nil), // 96: openshell.v1.ProviderProfile + (*StoredProviderProfile)(nil), // 97: openshell.v1.StoredProviderProfile + (*ProviderProfileResponse)(nil), // 98: openshell.v1.ProviderProfileResponse + (*ListProviderProfilesResponse)(nil), // 99: openshell.v1.ListProviderProfilesResponse + (*ImportProviderProfilesRequest)(nil), // 100: openshell.v1.ImportProviderProfilesRequest + (*ImportProviderProfilesResponse)(nil), // 101: openshell.v1.ImportProviderProfilesResponse + (*UpdateProviderProfilesRequest)(nil), // 102: openshell.v1.UpdateProviderProfilesRequest + (*UpdateProviderProfilesResponse)(nil), // 103: openshell.v1.UpdateProviderProfilesResponse + (*LintProviderProfilesRequest)(nil), // 104: openshell.v1.LintProviderProfilesRequest + (*LintProviderProfilesResponse)(nil), // 105: openshell.v1.LintProviderProfilesResponse + (*DeleteProviderResponse)(nil), // 106: openshell.v1.DeleteProviderResponse + (*DeleteProviderProfileRequest)(nil), // 107: openshell.v1.DeleteProviderProfileRequest + (*DeleteProviderProfileResponse)(nil), // 108: openshell.v1.DeleteProviderProfileResponse + (*GetSandboxProviderEnvironmentRequest)(nil), // 109: openshell.v1.GetSandboxProviderEnvironmentRequest + (*StaticCredentialEndpointBinding)(nil), // 110: openshell.v1.StaticCredentialEndpointBinding + (*StaticCredentialBinding)(nil), // 111: openshell.v1.StaticCredentialBinding + (*GetSandboxProviderEnvironmentResponse)(nil), // 112: openshell.v1.GetSandboxProviderEnvironmentResponse + (*UpdateConfigRequest)(nil), // 113: openshell.v1.UpdateConfigRequest + (*PolicyMergeOperation)(nil), // 114: openshell.v1.PolicyMergeOperation + (*AddNetworkRule)(nil), // 115: openshell.v1.AddNetworkRule + (*RemoveNetworkEndpoint)(nil), // 116: openshell.v1.RemoveNetworkEndpoint + (*RemoveNetworkRule)(nil), // 117: openshell.v1.RemoveNetworkRule + (*AddDenyRules)(nil), // 118: openshell.v1.AddDenyRules + (*AddAllowRules)(nil), // 119: openshell.v1.AddAllowRules + (*RemoveNetworkBinary)(nil), // 120: openshell.v1.RemoveNetworkBinary + (*UpdateConfigResponse)(nil), // 121: openshell.v1.UpdateConfigResponse + (*GetSandboxPolicyStatusRequest)(nil), // 122: openshell.v1.GetSandboxPolicyStatusRequest + (*GetSandboxPolicyStatusResponse)(nil), // 123: openshell.v1.GetSandboxPolicyStatusResponse + (*ListSandboxPoliciesRequest)(nil), // 124: openshell.v1.ListSandboxPoliciesRequest + (*ListSandboxPoliciesResponse)(nil), // 125: openshell.v1.ListSandboxPoliciesResponse + (*ReportPolicyStatusRequest)(nil), // 126: openshell.v1.ReportPolicyStatusRequest + (*ReportPolicyStatusResponse)(nil), // 127: openshell.v1.ReportPolicyStatusResponse + (*SandboxPolicyRevision)(nil), // 128: openshell.v1.SandboxPolicyRevision + (*GetSandboxLogsRequest)(nil), // 129: openshell.v1.GetSandboxLogsRequest + (*PushSandboxLogsRequest)(nil), // 130: openshell.v1.PushSandboxLogsRequest + (*PushSandboxLogsResponse)(nil), // 131: openshell.v1.PushSandboxLogsResponse + (*GetSandboxLogsResponse)(nil), // 132: openshell.v1.GetSandboxLogsResponse + (*SupervisorMessage)(nil), // 133: openshell.v1.SupervisorMessage + (*GatewayMessage)(nil), // 134: openshell.v1.GatewayMessage + (*SupervisorHello)(nil), // 135: openshell.v1.SupervisorHello + (*SessionAccepted)(nil), // 136: openshell.v1.SessionAccepted + (*SessionRejected)(nil), // 137: openshell.v1.SessionRejected + (*SupervisorHeartbeat)(nil), // 138: openshell.v1.SupervisorHeartbeat + (*GatewayHeartbeat)(nil), // 139: openshell.v1.GatewayHeartbeat + (*RelayOpen)(nil), // 140: openshell.v1.RelayOpen + (*SshRelayTarget)(nil), // 141: openshell.v1.SshRelayTarget + (*TcpRelayTarget)(nil), // 142: openshell.v1.TcpRelayTarget + (*RelayInit)(nil), // 143: openshell.v1.RelayInit + (*RelayFrame)(nil), // 144: openshell.v1.RelayFrame + (*RelayOpenResult)(nil), // 145: openshell.v1.RelayOpenResult + (*RelayClose)(nil), // 146: openshell.v1.RelayClose + (*L7RequestSample)(nil), // 147: openshell.v1.L7RequestSample + (*DenialSummary)(nil), // 148: openshell.v1.DenialSummary + (*DenialGroupCount)(nil), // 149: openshell.v1.DenialGroupCount + (*NetworkActivitySummary)(nil), // 150: openshell.v1.NetworkActivitySummary + (*PolicyChunk)(nil), // 151: openshell.v1.PolicyChunk + (*DraftPolicyUpdate)(nil), // 152: openshell.v1.DraftPolicyUpdate + (*SubmitPolicyAnalysisRequest)(nil), // 153: openshell.v1.SubmitPolicyAnalysisRequest + (*SubmitPolicyAnalysisResponse)(nil), // 154: openshell.v1.SubmitPolicyAnalysisResponse + (*GetDraftPolicyRequest)(nil), // 155: openshell.v1.GetDraftPolicyRequest + (*GetDraftPolicyResponse)(nil), // 156: openshell.v1.GetDraftPolicyResponse + (*ApproveDraftChunkRequest)(nil), // 157: openshell.v1.ApproveDraftChunkRequest + (*ApproveDraftChunkResponse)(nil), // 158: openshell.v1.ApproveDraftChunkResponse + (*RejectDraftChunkRequest)(nil), // 159: openshell.v1.RejectDraftChunkRequest + (*RejectDraftChunkResponse)(nil), // 160: openshell.v1.RejectDraftChunkResponse + (*ApproveAllDraftChunksRequest)(nil), // 161: openshell.v1.ApproveAllDraftChunksRequest + (*ApproveAllDraftChunksResponse)(nil), // 162: openshell.v1.ApproveAllDraftChunksResponse + (*EditDraftChunkRequest)(nil), // 163: openshell.v1.EditDraftChunkRequest + (*EditDraftChunkResponse)(nil), // 164: openshell.v1.EditDraftChunkResponse + (*UndoDraftChunkRequest)(nil), // 165: openshell.v1.UndoDraftChunkRequest + (*UndoDraftChunkResponse)(nil), // 166: openshell.v1.UndoDraftChunkResponse + (*ClearDraftChunksRequest)(nil), // 167: openshell.v1.ClearDraftChunksRequest + (*ClearDraftChunksResponse)(nil), // 168: openshell.v1.ClearDraftChunksResponse + (*GetDraftHistoryRequest)(nil), // 169: openshell.v1.GetDraftHistoryRequest + (*DraftHistoryEntry)(nil), // 170: openshell.v1.DraftHistoryEntry + (*GetDraftHistoryResponse)(nil), // 171: openshell.v1.GetDraftHistoryResponse + (*PolicyRevisionPayload)(nil), // 172: openshell.v1.PolicyRevisionPayload + (*DraftChunkPayload)(nil), // 173: openshell.v1.DraftChunkPayload + (*StoredPolicyRevision)(nil), // 174: openshell.v1.StoredPolicyRevision + (*StoredDraftChunk)(nil), // 175: openshell.v1.StoredDraftChunk + (*CreateWorkspaceRequest)(nil), // 176: openshell.v1.CreateWorkspaceRequest + (*CreateWorkspaceResponse)(nil), // 177: openshell.v1.CreateWorkspaceResponse + (*GetWorkspaceRequest)(nil), // 178: openshell.v1.GetWorkspaceRequest + (*GetWorkspaceResponse)(nil), // 179: openshell.v1.GetWorkspaceResponse + (*ListWorkspacesRequest)(nil), // 180: openshell.v1.ListWorkspacesRequest + (*ListWorkspacesResponse)(nil), // 181: openshell.v1.ListWorkspacesResponse + (*DeleteWorkspaceRequest)(nil), // 182: openshell.v1.DeleteWorkspaceRequest + (*DeleteWorkspaceResponse)(nil), // 183: openshell.v1.DeleteWorkspaceResponse + (*WorkspaceMember)(nil), // 184: openshell.v1.WorkspaceMember + (*AddWorkspaceMemberRequest)(nil), // 185: openshell.v1.AddWorkspaceMemberRequest + (*AddWorkspaceMemberResponse)(nil), // 186: openshell.v1.AddWorkspaceMemberResponse + (*RemoveWorkspaceMemberRequest)(nil), // 187: openshell.v1.RemoveWorkspaceMemberRequest + (*RemoveWorkspaceMemberResponse)(nil), // 188: openshell.v1.RemoveWorkspaceMemberResponse + (*ListWorkspaceMembersRequest)(nil), // 189: openshell.v1.ListWorkspaceMembersRequest + (*ListWorkspaceMembersResponse)(nil), // 190: openshell.v1.ListWorkspaceMembersResponse + (*ExtensionServiceCredential)(nil), // 191: openshell.v1.ExtensionServiceCredential + nil, // 192: openshell.v1.SandboxSpec.EnvironmentEntry + nil, // 193: openshell.v1.SandboxTemplate.LabelsEntry + nil, // 194: openshell.v1.SandboxTemplate.AnnotationsEntry + nil, // 195: openshell.v1.SandboxTemplate.EnvironmentEntry + nil, // 196: openshell.v1.PlatformEvent.MetadataEntry + nil, // 197: openshell.v1.CreateSandboxRequest.LabelsEntry + nil, // 198: openshell.v1.CreateSandboxRequest.AnnotationsEntry + nil, // 199: openshell.v1.ExecSandboxRequest.EnvironmentEntry + nil, // 200: openshell.v1.SandboxLogLine.FieldsEntry + nil, // 201: openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry + nil, // 202: openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry + nil, // 203: openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry + nil, // 204: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry nil, // 205: openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry nil, // 206: openshell.v1.ProviderProfile.AnnotationsEntry nil, // 207: openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry @@ -14544,21 +14600,21 @@ var file_openshell_proto_goTypes = []any{ (*sandboxv1.SandboxPolicy)(nil), // 218: openshell.sandbox.v1.SandboxPolicy (*structpb.Struct)(nil), // 219: google.protobuf.Struct (*datamodelv1.Provider)(nil), // 220: openshell.datamodel.v1.Provider - (*sandboxv1.NetworkEndpoint)(nil), // 221: openshell.sandbox.v1.NetworkEndpoint - (*sandboxv1.NetworkBinary)(nil), // 222: openshell.sandbox.v1.NetworkBinary - (*sandboxv1.SettingValue)(nil), // 223: openshell.sandbox.v1.SettingValue - (*sandboxv1.NetworkPolicyRule)(nil), // 224: openshell.sandbox.v1.NetworkPolicyRule - (*sandboxv1.L7DenyRule)(nil), // 225: openshell.sandbox.v1.L7DenyRule - (*sandboxv1.L7Rule)(nil), // 226: openshell.sandbox.v1.L7Rule - (*datamodelv1.Workspace)(nil), // 227: openshell.datamodel.v1.Workspace - (*datamodelv1.CredentialHandle)(nil), // 228: openshell.datamodel.v1.CredentialHandle + (*datamodelv1.CredentialHandle)(nil), // 221: openshell.datamodel.v1.CredentialHandle + (*sandboxv1.NetworkEndpoint)(nil), // 222: openshell.sandbox.v1.NetworkEndpoint + (*sandboxv1.NetworkBinary)(nil), // 223: openshell.sandbox.v1.NetworkBinary + (*sandboxv1.SettingValue)(nil), // 224: openshell.sandbox.v1.SettingValue + (*sandboxv1.NetworkPolicyRule)(nil), // 225: openshell.sandbox.v1.NetworkPolicyRule + (*sandboxv1.L7DenyRule)(nil), // 226: openshell.sandbox.v1.L7DenyRule + (*sandboxv1.L7Rule)(nil), // 227: openshell.sandbox.v1.L7Rule + (*datamodelv1.Workspace)(nil), // 228: openshell.datamodel.v1.Workspace (*sandboxv1.GetSandboxConfigRequest)(nil), // 229: openshell.sandbox.v1.GetSandboxConfigRequest (*sandboxv1.GetGatewayConfigRequest)(nil), // 230: openshell.sandbox.v1.GetGatewayConfigRequest (*sandboxv1.GetSandboxConfigResponse)(nil), // 231: openshell.sandbox.v1.GetSandboxConfigResponse (*sandboxv1.GetGatewayConfigResponse)(nil), // 232: openshell.sandbox.v1.GetGatewayConfigResponse } var file_openshell_proto_depIdxs = []int32{ - 190, // 0: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential + 191, // 0: openshell.v1.RefreshSandboxTokenResponse.extension_credentials:type_name -> openshell.v1.ExtensionServiceCredential 4, // 1: openshell.v1.HealthResponse.status:type_name -> openshell.v1.ServiceStatus 4, // 2: openshell.v1.GetGatewayInfoResponse.status:type_name -> openshell.v1.ServiceStatus 16, // 3: openshell.v1.GetGatewayInfoResponse.compute_drivers:type_name -> openshell.v1.ComputeDriverInfo @@ -14566,22 +14622,22 @@ var file_openshell_proto_depIdxs = []int32{ 217, // 5: openshell.v1.Sandbox.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 19, // 6: openshell.v1.Sandbox.spec:type_name -> openshell.v1.SandboxSpec 23, // 7: openshell.v1.Sandbox.status:type_name -> openshell.v1.SandboxStatus - 191, // 8: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry + 192, // 8: openshell.v1.SandboxSpec.environment:type_name -> openshell.v1.SandboxSpec.EnvironmentEntry 22, // 9: openshell.v1.SandboxSpec.template:type_name -> openshell.v1.SandboxTemplate 218, // 10: openshell.v1.SandboxSpec.policy:type_name -> openshell.sandbox.v1.SandboxPolicy 20, // 11: openshell.v1.SandboxSpec.resource_requirements:type_name -> openshell.v1.ResourceRequirements 21, // 12: openshell.v1.ResourceRequirements.gpu:type_name -> openshell.v1.GpuResourceRequirements - 192, // 13: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry - 193, // 14: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry - 194, // 15: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry + 193, // 13: openshell.v1.SandboxTemplate.labels:type_name -> openshell.v1.SandboxTemplate.LabelsEntry + 194, // 14: openshell.v1.SandboxTemplate.annotations:type_name -> openshell.v1.SandboxTemplate.AnnotationsEntry + 195, // 15: openshell.v1.SandboxTemplate.environment:type_name -> openshell.v1.SandboxTemplate.EnvironmentEntry 219, // 16: openshell.v1.SandboxTemplate.resources:type_name -> google.protobuf.Struct 219, // 17: openshell.v1.SandboxTemplate.driver_config:type_name -> google.protobuf.Struct 24, // 18: openshell.v1.SandboxStatus.conditions:type_name -> openshell.v1.SandboxCondition 0, // 19: openshell.v1.SandboxStatus.phase:type_name -> openshell.v1.SandboxPhase - 195, // 20: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry + 196, // 20: openshell.v1.PlatformEvent.metadata:type_name -> openshell.v1.PlatformEvent.MetadataEntry 19, // 21: openshell.v1.CreateSandboxRequest.spec:type_name -> openshell.v1.SandboxSpec - 196, // 22: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry - 197, // 23: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry + 197, // 22: openshell.v1.CreateSandboxRequest.labels:type_name -> openshell.v1.CreateSandboxRequest.LabelsEntry + 198, // 23: openshell.v1.CreateSandboxRequest.annotations:type_name -> openshell.v1.CreateSandboxRequest.AnnotationsEntry 18, // 24: openshell.v1.SandboxResponse.sandbox:type_name -> openshell.v1.Sandbox 18, // 25: openshell.v1.ListSandboxesResponse.sandboxes:type_name -> openshell.v1.Sandbox 220, // 26: openshell.v1.ListSandboxProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider @@ -14590,12 +14646,12 @@ var file_openshell_proto_depIdxs = []int32{ 50, // 29: openshell.v1.ListServicesResponse.services:type_name -> openshell.v1.ServiceEndpointResponse 217, // 30: openshell.v1.ServiceEndpoint.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 49, // 31: openshell.v1.ServiceEndpointResponse.endpoint:type_name -> openshell.v1.ServiceEndpoint - 198, // 32: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry + 199, // 32: openshell.v1.ExecSandboxRequest.environment:type_name -> openshell.v1.ExecSandboxRequest.EnvironmentEntry 54, // 33: openshell.v1.ExecSandboxEvent.stdout:type_name -> openshell.v1.ExecSandboxStdout 55, // 34: openshell.v1.ExecSandboxEvent.stderr:type_name -> openshell.v1.ExecSandboxStderr 56, // 35: openshell.v1.ExecSandboxEvent.exit:type_name -> openshell.v1.ExecSandboxExit - 140, // 36: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget - 141, // 37: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget + 141, // 36: openshell.v1.TcpForwardInit.ssh:type_name -> openshell.v1.SshRelayTarget + 142, // 37: openshell.v1.TcpForwardInit.tcp:type_name -> openshell.v1.TcpRelayTarget 58, // 38: openshell.v1.TcpForwardFrame.init:type_name -> openshell.v1.TcpForwardInit 53, // 39: openshell.v1.ExecSandboxInput.start:type_name -> openshell.v1.ExecSandboxRequest 61, // 40: openshell.v1.ExecSandboxInput.resize:type_name -> openshell.v1.ExecSandboxWindowResize @@ -14604,14 +14660,14 @@ var file_openshell_proto_depIdxs = []int32{ 65, // 43: openshell.v1.SandboxStreamEvent.log:type_name -> openshell.v1.SandboxLogLine 25, // 44: openshell.v1.SandboxStreamEvent.event:type_name -> openshell.v1.PlatformEvent 66, // 45: openshell.v1.SandboxStreamEvent.warning:type_name -> openshell.v1.SandboxStreamWarning - 151, // 46: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate - 199, // 47: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry + 152, // 46: openshell.v1.SandboxStreamEvent.draft_policy_update:type_name -> openshell.v1.DraftPolicyUpdate + 200, // 47: openshell.v1.SandboxLogLine.fields:type_name -> openshell.v1.SandboxLogLine.FieldsEntry 220, // 48: openshell.v1.CreateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider 220, // 49: openshell.v1.UpdateProviderRequest.provider:type_name -> openshell.datamodel.v1.Provider - 200, // 50: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry + 201, // 50: openshell.v1.UpdateProviderRequest.credential_expires_at_ms:type_name -> openshell.v1.UpdateProviderRequest.CredentialExpiresAtMsEntry 220, // 51: openshell.v1.ProviderResponse.provider:type_name -> openshell.datamodel.v1.Provider 220, // 52: openshell.v1.ListProvidersResponse.providers:type_name -> openshell.datamodel.v1.Provider - 95, // 53: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile + 96, // 53: openshell.v1.ProviderProfileImportItem.profile:type_name -> openshell.v1.ProviderProfile 78, // 54: openshell.v1.ProviderCredentialTokenGrant.audience_overrides:type_name -> openshell.v1.ProviderCredentialTokenGrantAudienceOverride 83, // 55: openshell.v1.ProviderProfileCredential.refresh:type_name -> openshell.v1.ProviderCredentialRefresh 79, // 56: openshell.v1.ProviderProfileCredential.token_grant:type_name -> openshell.v1.ProviderCredentialTokenGrant @@ -14621,98 +14677,98 @@ var file_openshell_proto_depIdxs = []int32{ 1, // 60: openshell.v1.ProviderCredentialRefreshStatus.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy 217, // 61: openshell.v1.StoredProviderCredentialRefreshState.metadata:type_name -> openshell.datamodel.v1.ObjectMeta 1, // 62: openshell.v1.StoredProviderCredentialRefreshState.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 201, // 63: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry - 202, // 64: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry - 203, // 65: openshell.v1.StoredProviderCredentialRefreshState.secret_material_handles:type_name -> openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry - 204, // 66: openshell.v1.StoredProviderCredentialRefreshState.pending_secret_deletions:type_name -> openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntry - 84, // 67: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 1, // 68: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy - 205, // 69: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry - 84, // 70: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 84, // 71: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus - 2, // 72: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory - 80, // 73: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential - 221, // 74: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint - 222, // 75: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary - 85, // 76: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery - 206, // 77: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry - 217, // 78: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 95, // 79: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile - 95, // 80: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile - 95, // 81: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 76, // 82: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 77, // 83: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 95, // 84: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile - 76, // 85: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem - 77, // 86: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 95, // 87: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile - 76, // 88: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem - 77, // 89: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic - 109, // 90: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding - 207, // 91: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry - 208, // 92: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry - 209, // 93: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry - 210, // 94: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry - 218, // 95: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 223, // 96: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue - 113, // 97: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation - 211, // 98: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry - 114, // 99: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule - 115, // 100: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint - 116, // 101: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule - 117, // 102: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules - 118, // 103: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules - 119, // 104: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary - 224, // 105: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 225, // 106: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule - 226, // 107: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule - 212, // 108: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry - 127, // 109: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision - 127, // 110: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision - 3, // 111: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus - 3, // 112: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus - 218, // 113: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 213, // 114: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry - 65, // 115: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine - 65, // 116: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine - 134, // 117: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello - 137, // 118: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat - 144, // 119: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult - 145, // 120: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose - 135, // 121: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted - 136, // 122: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected - 138, // 123: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat - 139, // 124: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen - 145, // 125: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose - 140, // 126: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget - 141, // 127: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget - 142, // 128: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit - 146, // 129: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample - 148, // 130: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount - 224, // 131: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 147, // 132: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary - 150, // 133: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk - 149, // 134: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary - 150, // 135: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk - 224, // 136: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 169, // 137: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry - 218, // 138: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy - 214, // 139: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry - 224, // 140: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule - 215, // 141: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry - 216, // 142: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry - 227, // 143: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 227, // 144: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace - 227, // 145: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace - 217, // 146: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta - 5, // 147: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole - 5, // 148: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole - 183, // 149: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember - 183, // 150: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember - 228, // 151: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle - 228, // 152: openshell.v1.StoredProviderCredentialRefreshState.PendingSecretDeletionsEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle + 202, // 63: openshell.v1.StoredProviderCredentialRefreshState.material:type_name -> openshell.v1.StoredProviderCredentialRefreshState.MaterialEntry + 203, // 64: openshell.v1.StoredProviderCredentialRefreshState.additional_output_keys:type_name -> openshell.v1.StoredProviderCredentialRefreshState.AdditionalOutputKeysEntry + 204, // 65: openshell.v1.StoredProviderCredentialRefreshState.secret_material_handles:type_name -> openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry + 87, // 66: openshell.v1.StoredProviderCredentialRefreshState.pending_secret_deletions:type_name -> openshell.v1.StoredRefreshMaterialDeletion + 221, // 67: openshell.v1.StoredRefreshMaterialDeletion.handle:type_name -> openshell.datamodel.v1.CredentialHandle + 84, // 68: openshell.v1.GetProviderRefreshStatusResponse.credentials:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 1, // 69: openshell.v1.ConfigureProviderRefreshRequest.strategy:type_name -> openshell.v1.ProviderCredentialRefreshStrategy + 205, // 70: openshell.v1.ConfigureProviderRefreshRequest.material:type_name -> openshell.v1.ConfigureProviderRefreshRequest.MaterialEntry + 84, // 71: openshell.v1.ConfigureProviderRefreshResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 84, // 72: openshell.v1.RotateProviderCredentialResponse.status:type_name -> openshell.v1.ProviderCredentialRefreshStatus + 2, // 73: openshell.v1.ProviderProfile.category:type_name -> openshell.v1.ProviderProfileCategory + 80, // 74: openshell.v1.ProviderProfile.credentials:type_name -> openshell.v1.ProviderProfileCredential + 222, // 75: openshell.v1.ProviderProfile.endpoints:type_name -> openshell.sandbox.v1.NetworkEndpoint + 223, // 76: openshell.v1.ProviderProfile.binaries:type_name -> openshell.sandbox.v1.NetworkBinary + 85, // 77: openshell.v1.ProviderProfile.discovery:type_name -> openshell.v1.ProviderProfileDiscovery + 206, // 78: openshell.v1.ProviderProfile.annotations:type_name -> openshell.v1.ProviderProfile.AnnotationsEntry + 217, // 79: openshell.v1.StoredProviderProfile.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 96, // 80: openshell.v1.StoredProviderProfile.profile:type_name -> openshell.v1.ProviderProfile + 96, // 81: openshell.v1.ProviderProfileResponse.profile:type_name -> openshell.v1.ProviderProfile + 96, // 82: openshell.v1.ListProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 76, // 83: openshell.v1.ImportProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 84: openshell.v1.ImportProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 96, // 85: openshell.v1.ImportProviderProfilesResponse.profiles:type_name -> openshell.v1.ProviderProfile + 76, // 86: openshell.v1.UpdateProviderProfilesRequest.profile:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 87: openshell.v1.UpdateProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 96, // 88: openshell.v1.UpdateProviderProfilesResponse.profile:type_name -> openshell.v1.ProviderProfile + 76, // 89: openshell.v1.LintProviderProfilesRequest.profiles:type_name -> openshell.v1.ProviderProfileImportItem + 77, // 90: openshell.v1.LintProviderProfilesResponse.diagnostics:type_name -> openshell.v1.ProviderProfileDiagnostic + 110, // 91: openshell.v1.StaticCredentialBinding.endpoints:type_name -> openshell.v1.StaticCredentialEndpointBinding + 207, // 92: openshell.v1.GetSandboxProviderEnvironmentResponse.environment:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.EnvironmentEntry + 208, // 93: openshell.v1.GetSandboxProviderEnvironmentResponse.credential_expires_at_ms:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.CredentialExpiresAtMsEntry + 209, // 94: openshell.v1.GetSandboxProviderEnvironmentResponse.dynamic_credentials:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry + 210, // 95: openshell.v1.GetSandboxProviderEnvironmentResponse.static_credential_bindings:type_name -> openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry + 218, // 96: openshell.v1.UpdateConfigRequest.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 224, // 97: openshell.v1.UpdateConfigRequest.setting_value:type_name -> openshell.sandbox.v1.SettingValue + 114, // 98: openshell.v1.UpdateConfigRequest.merge_operations:type_name -> openshell.v1.PolicyMergeOperation + 211, // 99: openshell.v1.UpdateConfigRequest.annotations:type_name -> openshell.v1.UpdateConfigRequest.AnnotationsEntry + 115, // 100: openshell.v1.PolicyMergeOperation.add_rule:type_name -> openshell.v1.AddNetworkRule + 116, // 101: openshell.v1.PolicyMergeOperation.remove_endpoint:type_name -> openshell.v1.RemoveNetworkEndpoint + 117, // 102: openshell.v1.PolicyMergeOperation.remove_rule:type_name -> openshell.v1.RemoveNetworkRule + 118, // 103: openshell.v1.PolicyMergeOperation.add_deny_rules:type_name -> openshell.v1.AddDenyRules + 119, // 104: openshell.v1.PolicyMergeOperation.add_allow_rules:type_name -> openshell.v1.AddAllowRules + 120, // 105: openshell.v1.PolicyMergeOperation.remove_binary:type_name -> openshell.v1.RemoveNetworkBinary + 225, // 106: openshell.v1.AddNetworkRule.rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 226, // 107: openshell.v1.AddDenyRules.deny_rules:type_name -> openshell.sandbox.v1.L7DenyRule + 227, // 108: openshell.v1.AddAllowRules.rules:type_name -> openshell.sandbox.v1.L7Rule + 212, // 109: openshell.v1.UpdateConfigResponse.annotations:type_name -> openshell.v1.UpdateConfigResponse.AnnotationsEntry + 128, // 110: openshell.v1.GetSandboxPolicyStatusResponse.revision:type_name -> openshell.v1.SandboxPolicyRevision + 128, // 111: openshell.v1.ListSandboxPoliciesResponse.revisions:type_name -> openshell.v1.SandboxPolicyRevision + 3, // 112: openshell.v1.ReportPolicyStatusRequest.status:type_name -> openshell.v1.PolicyStatus + 3, // 113: openshell.v1.SandboxPolicyRevision.status:type_name -> openshell.v1.PolicyStatus + 218, // 114: openshell.v1.SandboxPolicyRevision.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 213, // 115: openshell.v1.SandboxPolicyRevision.provenance:type_name -> openshell.v1.SandboxPolicyRevision.ProvenanceEntry + 65, // 116: openshell.v1.PushSandboxLogsRequest.logs:type_name -> openshell.v1.SandboxLogLine + 65, // 117: openshell.v1.GetSandboxLogsResponse.logs:type_name -> openshell.v1.SandboxLogLine + 135, // 118: openshell.v1.SupervisorMessage.hello:type_name -> openshell.v1.SupervisorHello + 138, // 119: openshell.v1.SupervisorMessage.heartbeat:type_name -> openshell.v1.SupervisorHeartbeat + 145, // 120: openshell.v1.SupervisorMessage.relay_open_result:type_name -> openshell.v1.RelayOpenResult + 146, // 121: openshell.v1.SupervisorMessage.relay_close:type_name -> openshell.v1.RelayClose + 136, // 122: openshell.v1.GatewayMessage.session_accepted:type_name -> openshell.v1.SessionAccepted + 137, // 123: openshell.v1.GatewayMessage.session_rejected:type_name -> openshell.v1.SessionRejected + 139, // 124: openshell.v1.GatewayMessage.heartbeat:type_name -> openshell.v1.GatewayHeartbeat + 140, // 125: openshell.v1.GatewayMessage.relay_open:type_name -> openshell.v1.RelayOpen + 146, // 126: openshell.v1.GatewayMessage.relay_close:type_name -> openshell.v1.RelayClose + 141, // 127: openshell.v1.RelayOpen.ssh:type_name -> openshell.v1.SshRelayTarget + 142, // 128: openshell.v1.RelayOpen.tcp:type_name -> openshell.v1.TcpRelayTarget + 143, // 129: openshell.v1.RelayFrame.init:type_name -> openshell.v1.RelayInit + 147, // 130: openshell.v1.DenialSummary.l7_request_samples:type_name -> openshell.v1.L7RequestSample + 149, // 131: openshell.v1.NetworkActivitySummary.denials_by_group:type_name -> openshell.v1.DenialGroupCount + 225, // 132: openshell.v1.PolicyChunk.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 148, // 133: openshell.v1.SubmitPolicyAnalysisRequest.summaries:type_name -> openshell.v1.DenialSummary + 151, // 134: openshell.v1.SubmitPolicyAnalysisRequest.proposed_chunks:type_name -> openshell.v1.PolicyChunk + 150, // 135: openshell.v1.SubmitPolicyAnalysisRequest.network_activity_summaries:type_name -> openshell.v1.NetworkActivitySummary + 151, // 136: openshell.v1.GetDraftPolicyResponse.chunks:type_name -> openshell.v1.PolicyChunk + 225, // 137: openshell.v1.EditDraftChunkRequest.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 170, // 138: openshell.v1.GetDraftHistoryResponse.entries:type_name -> openshell.v1.DraftHistoryEntry + 218, // 139: openshell.v1.PolicyRevisionPayload.policy:type_name -> openshell.sandbox.v1.SandboxPolicy + 214, // 140: openshell.v1.PolicyRevisionPayload.provenance:type_name -> openshell.v1.PolicyRevisionPayload.ProvenanceEntry + 225, // 141: openshell.v1.DraftChunkPayload.proposed_rule:type_name -> openshell.sandbox.v1.NetworkPolicyRule + 215, // 142: openshell.v1.StoredPolicyRevision.provenance:type_name -> openshell.v1.StoredPolicyRevision.ProvenanceEntry + 216, // 143: openshell.v1.CreateWorkspaceRequest.labels:type_name -> openshell.v1.CreateWorkspaceRequest.LabelsEntry + 228, // 144: openshell.v1.CreateWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 228, // 145: openshell.v1.GetWorkspaceResponse.workspace:type_name -> openshell.datamodel.v1.Workspace + 228, // 146: openshell.v1.ListWorkspacesResponse.workspaces:type_name -> openshell.datamodel.v1.Workspace + 217, // 147: openshell.v1.WorkspaceMember.metadata:type_name -> openshell.datamodel.v1.ObjectMeta + 5, // 148: openshell.v1.WorkspaceMember.role:type_name -> openshell.v1.WorkspaceRole + 5, // 149: openshell.v1.AddWorkspaceMemberRequest.role:type_name -> openshell.v1.WorkspaceRole + 184, // 150: openshell.v1.AddWorkspaceMemberResponse.member:type_name -> openshell.v1.WorkspaceMember + 184, // 151: openshell.v1.ListWorkspaceMembersResponse.members:type_name -> openshell.v1.WorkspaceMember + 221, // 152: openshell.v1.StoredProviderCredentialRefreshState.SecretMaterialHandlesEntry.value:type_name -> openshell.datamodel.v1.CredentialHandle 80, // 153: openshell.v1.GetSandboxProviderEnvironmentResponse.DynamicCredentialsEntry.value:type_name -> openshell.v1.ProviderProfileCredential - 110, // 154: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding + 111, // 154: openshell.v1.GetSandboxProviderEnvironmentResponse.StaticCredentialBindingsEntry.value:type_name -> openshell.v1.StaticCredentialBinding 10, // 155: openshell.v1.OpenShell.Health:input_type -> openshell.v1.HealthRequest 12, // 156: openshell.v1.OpenShell.GetCurrentUser:input_type -> openshell.v1.GetCurrentUserRequest 14, // 157: openshell.v1.OpenShell.GetGatewayInfo:input_type -> openshell.v1.GetGatewayInfoRequest @@ -14739,46 +14795,46 @@ var file_openshell_proto_depIdxs = []int32{ 69, // 178: openshell.v1.OpenShell.ListProviders:input_type -> openshell.v1.ListProvidersRequest 74, // 179: openshell.v1.OpenShell.ListProviderProfiles:input_type -> openshell.v1.ListProviderProfilesRequest 75, // 180: openshell.v1.OpenShell.GetProviderProfile:input_type -> openshell.v1.GetProviderProfileRequest - 99, // 181: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest - 101, // 182: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest - 103, // 183: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest + 100, // 181: openshell.v1.OpenShell.ImportProviderProfiles:input_type -> openshell.v1.ImportProviderProfilesRequest + 102, // 182: openshell.v1.OpenShell.UpdateProviderProfiles:input_type -> openshell.v1.UpdateProviderProfilesRequest + 104, // 183: openshell.v1.OpenShell.LintProviderProfiles:input_type -> openshell.v1.LintProviderProfilesRequest 70, // 184: openshell.v1.OpenShell.UpdateProvider:input_type -> openshell.v1.UpdateProviderRequest - 87, // 185: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest - 89, // 186: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest - 91, // 187: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest - 93, // 188: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest + 88, // 185: openshell.v1.OpenShell.GetProviderRefreshStatus:input_type -> openshell.v1.GetProviderRefreshStatusRequest + 90, // 186: openshell.v1.OpenShell.ConfigureProviderRefresh:input_type -> openshell.v1.ConfigureProviderRefreshRequest + 92, // 187: openshell.v1.OpenShell.RotateProviderCredential:input_type -> openshell.v1.RotateProviderCredentialRequest + 94, // 188: openshell.v1.OpenShell.DeleteProviderRefresh:input_type -> openshell.v1.DeleteProviderRefreshRequest 71, // 189: openshell.v1.OpenShell.DeleteProvider:input_type -> openshell.v1.DeleteProviderRequest - 106, // 190: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest + 107, // 190: openshell.v1.OpenShell.DeleteProviderProfile:input_type -> openshell.v1.DeleteProviderProfileRequest 229, // 191: openshell.v1.OpenShell.GetSandboxConfig:input_type -> openshell.sandbox.v1.GetSandboxConfigRequest 230, // 192: openshell.v1.OpenShell.GetGatewayConfig:input_type -> openshell.sandbox.v1.GetGatewayConfigRequest - 112, // 193: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest - 121, // 194: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest - 123, // 195: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest - 125, // 196: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest - 108, // 197: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest - 128, // 198: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest - 129, // 199: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest - 132, // 200: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage - 143, // 201: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame + 113, // 193: openshell.v1.OpenShell.UpdateConfig:input_type -> openshell.v1.UpdateConfigRequest + 122, // 194: openshell.v1.OpenShell.GetSandboxPolicyStatus:input_type -> openshell.v1.GetSandboxPolicyStatusRequest + 124, // 195: openshell.v1.OpenShell.ListSandboxPolicies:input_type -> openshell.v1.ListSandboxPoliciesRequest + 126, // 196: openshell.v1.OpenShell.ReportPolicyStatus:input_type -> openshell.v1.ReportPolicyStatusRequest + 109, // 197: openshell.v1.OpenShell.GetSandboxProviderEnvironment:input_type -> openshell.v1.GetSandboxProviderEnvironmentRequest + 129, // 198: openshell.v1.OpenShell.GetSandboxLogs:input_type -> openshell.v1.GetSandboxLogsRequest + 130, // 199: openshell.v1.OpenShell.PushSandboxLogs:input_type -> openshell.v1.PushSandboxLogsRequest + 133, // 200: openshell.v1.OpenShell.ConnectSupervisor:input_type -> openshell.v1.SupervisorMessage + 144, // 201: openshell.v1.OpenShell.RelayStream:input_type -> openshell.v1.RelayFrame 63, // 202: openshell.v1.OpenShell.WatchSandbox:input_type -> openshell.v1.WatchSandboxRequest - 152, // 203: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest - 154, // 204: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest - 156, // 205: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest - 158, // 206: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest - 160, // 207: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest - 162, // 208: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest - 164, // 209: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest - 166, // 210: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest - 168, // 211: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest + 153, // 203: openshell.v1.OpenShell.SubmitPolicyAnalysis:input_type -> openshell.v1.SubmitPolicyAnalysisRequest + 155, // 204: openshell.v1.OpenShell.GetDraftPolicy:input_type -> openshell.v1.GetDraftPolicyRequest + 157, // 205: openshell.v1.OpenShell.ApproveDraftChunk:input_type -> openshell.v1.ApproveDraftChunkRequest + 159, // 206: openshell.v1.OpenShell.RejectDraftChunk:input_type -> openshell.v1.RejectDraftChunkRequest + 161, // 207: openshell.v1.OpenShell.ApproveAllDraftChunks:input_type -> openshell.v1.ApproveAllDraftChunksRequest + 163, // 208: openshell.v1.OpenShell.EditDraftChunk:input_type -> openshell.v1.EditDraftChunkRequest + 165, // 209: openshell.v1.OpenShell.UndoDraftChunk:input_type -> openshell.v1.UndoDraftChunkRequest + 167, // 210: openshell.v1.OpenShell.ClearDraftChunks:input_type -> openshell.v1.ClearDraftChunksRequest + 169, // 211: openshell.v1.OpenShell.GetDraftHistory:input_type -> openshell.v1.GetDraftHistoryRequest 6, // 212: openshell.v1.OpenShell.IssueSandboxToken:input_type -> openshell.v1.IssueSandboxTokenRequest 8, // 213: openshell.v1.OpenShell.RefreshSandboxToken:input_type -> openshell.v1.RefreshSandboxTokenRequest - 175, // 214: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest - 177, // 215: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest - 179, // 216: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest - 181, // 217: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest - 184, // 218: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest - 186, // 219: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest - 188, // 220: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest + 176, // 214: openshell.v1.OpenShell.CreateWorkspace:input_type -> openshell.v1.CreateWorkspaceRequest + 178, // 215: openshell.v1.OpenShell.GetWorkspace:input_type -> openshell.v1.GetWorkspaceRequest + 180, // 216: openshell.v1.OpenShell.ListWorkspaces:input_type -> openshell.v1.ListWorkspacesRequest + 182, // 217: openshell.v1.OpenShell.DeleteWorkspace:input_type -> openshell.v1.DeleteWorkspaceRequest + 185, // 218: openshell.v1.OpenShell.AddWorkspaceMember:input_type -> openshell.v1.AddWorkspaceMemberRequest + 187, // 219: openshell.v1.OpenShell.RemoveWorkspaceMember:input_type -> openshell.v1.RemoveWorkspaceMemberRequest + 189, // 220: openshell.v1.OpenShell.ListWorkspaceMembers:input_type -> openshell.v1.ListWorkspaceMembersRequest 11, // 221: openshell.v1.OpenShell.Health:output_type -> openshell.v1.HealthResponse 13, // 222: openshell.v1.OpenShell.GetCurrentUser:output_type -> openshell.v1.GetCurrentUserResponse 15, // 223: openshell.v1.OpenShell.GetGatewayInfo:output_type -> openshell.v1.GetGatewayInfoResponse @@ -14803,48 +14859,48 @@ var file_openshell_proto_depIdxs = []int32{ 72, // 242: openshell.v1.OpenShell.CreateProvider:output_type -> openshell.v1.ProviderResponse 72, // 243: openshell.v1.OpenShell.GetProvider:output_type -> openshell.v1.ProviderResponse 73, // 244: openshell.v1.OpenShell.ListProviders:output_type -> openshell.v1.ListProvidersResponse - 98, // 245: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse - 97, // 246: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse - 100, // 247: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse - 102, // 248: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse - 104, // 249: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse + 99, // 245: openshell.v1.OpenShell.ListProviderProfiles:output_type -> openshell.v1.ListProviderProfilesResponse + 98, // 246: openshell.v1.OpenShell.GetProviderProfile:output_type -> openshell.v1.ProviderProfileResponse + 101, // 247: openshell.v1.OpenShell.ImportProviderProfiles:output_type -> openshell.v1.ImportProviderProfilesResponse + 103, // 248: openshell.v1.OpenShell.UpdateProviderProfiles:output_type -> openshell.v1.UpdateProviderProfilesResponse + 105, // 249: openshell.v1.OpenShell.LintProviderProfiles:output_type -> openshell.v1.LintProviderProfilesResponse 72, // 250: openshell.v1.OpenShell.UpdateProvider:output_type -> openshell.v1.ProviderResponse - 88, // 251: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse - 90, // 252: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse - 92, // 253: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse - 94, // 254: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse - 105, // 255: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse - 107, // 256: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse + 89, // 251: openshell.v1.OpenShell.GetProviderRefreshStatus:output_type -> openshell.v1.GetProviderRefreshStatusResponse + 91, // 252: openshell.v1.OpenShell.ConfigureProviderRefresh:output_type -> openshell.v1.ConfigureProviderRefreshResponse + 93, // 253: openshell.v1.OpenShell.RotateProviderCredential:output_type -> openshell.v1.RotateProviderCredentialResponse + 95, // 254: openshell.v1.OpenShell.DeleteProviderRefresh:output_type -> openshell.v1.DeleteProviderRefreshResponse + 106, // 255: openshell.v1.OpenShell.DeleteProvider:output_type -> openshell.v1.DeleteProviderResponse + 108, // 256: openshell.v1.OpenShell.DeleteProviderProfile:output_type -> openshell.v1.DeleteProviderProfileResponse 231, // 257: openshell.v1.OpenShell.GetSandboxConfig:output_type -> openshell.sandbox.v1.GetSandboxConfigResponse 232, // 258: openshell.v1.OpenShell.GetGatewayConfig:output_type -> openshell.sandbox.v1.GetGatewayConfigResponse - 120, // 259: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse - 122, // 260: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse - 124, // 261: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse - 126, // 262: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse - 111, // 263: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse - 131, // 264: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse - 130, // 265: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse - 133, // 266: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage - 143, // 267: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame + 121, // 259: openshell.v1.OpenShell.UpdateConfig:output_type -> openshell.v1.UpdateConfigResponse + 123, // 260: openshell.v1.OpenShell.GetSandboxPolicyStatus:output_type -> openshell.v1.GetSandboxPolicyStatusResponse + 125, // 261: openshell.v1.OpenShell.ListSandboxPolicies:output_type -> openshell.v1.ListSandboxPoliciesResponse + 127, // 262: openshell.v1.OpenShell.ReportPolicyStatus:output_type -> openshell.v1.ReportPolicyStatusResponse + 112, // 263: openshell.v1.OpenShell.GetSandboxProviderEnvironment:output_type -> openshell.v1.GetSandboxProviderEnvironmentResponse + 132, // 264: openshell.v1.OpenShell.GetSandboxLogs:output_type -> openshell.v1.GetSandboxLogsResponse + 131, // 265: openshell.v1.OpenShell.PushSandboxLogs:output_type -> openshell.v1.PushSandboxLogsResponse + 134, // 266: openshell.v1.OpenShell.ConnectSupervisor:output_type -> openshell.v1.GatewayMessage + 144, // 267: openshell.v1.OpenShell.RelayStream:output_type -> openshell.v1.RelayFrame 64, // 268: openshell.v1.OpenShell.WatchSandbox:output_type -> openshell.v1.SandboxStreamEvent - 153, // 269: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse - 155, // 270: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse - 157, // 271: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse - 159, // 272: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse - 161, // 273: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse - 163, // 274: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse - 165, // 275: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse - 167, // 276: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse - 170, // 277: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse + 154, // 269: openshell.v1.OpenShell.SubmitPolicyAnalysis:output_type -> openshell.v1.SubmitPolicyAnalysisResponse + 156, // 270: openshell.v1.OpenShell.GetDraftPolicy:output_type -> openshell.v1.GetDraftPolicyResponse + 158, // 271: openshell.v1.OpenShell.ApproveDraftChunk:output_type -> openshell.v1.ApproveDraftChunkResponse + 160, // 272: openshell.v1.OpenShell.RejectDraftChunk:output_type -> openshell.v1.RejectDraftChunkResponse + 162, // 273: openshell.v1.OpenShell.ApproveAllDraftChunks:output_type -> openshell.v1.ApproveAllDraftChunksResponse + 164, // 274: openshell.v1.OpenShell.EditDraftChunk:output_type -> openshell.v1.EditDraftChunkResponse + 166, // 275: openshell.v1.OpenShell.UndoDraftChunk:output_type -> openshell.v1.UndoDraftChunkResponse + 168, // 276: openshell.v1.OpenShell.ClearDraftChunks:output_type -> openshell.v1.ClearDraftChunksResponse + 171, // 277: openshell.v1.OpenShell.GetDraftHistory:output_type -> openshell.v1.GetDraftHistoryResponse 7, // 278: openshell.v1.OpenShell.IssueSandboxToken:output_type -> openshell.v1.IssueSandboxTokenResponse 9, // 279: openshell.v1.OpenShell.RefreshSandboxToken:output_type -> openshell.v1.RefreshSandboxTokenResponse - 176, // 280: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse - 178, // 281: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse - 180, // 282: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse - 182, // 283: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse - 185, // 284: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse - 187, // 285: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse - 189, // 286: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse + 177, // 280: openshell.v1.OpenShell.CreateWorkspace:output_type -> openshell.v1.CreateWorkspaceResponse + 179, // 281: openshell.v1.OpenShell.GetWorkspace:output_type -> openshell.v1.GetWorkspaceResponse + 181, // 282: openshell.v1.OpenShell.ListWorkspaces:output_type -> openshell.v1.ListWorkspacesResponse + 183, // 283: openshell.v1.OpenShell.DeleteWorkspace:output_type -> openshell.v1.DeleteWorkspaceResponse + 186, // 284: openshell.v1.OpenShell.AddWorkspaceMember:output_type -> openshell.v1.AddWorkspaceMemberResponse + 188, // 285: openshell.v1.OpenShell.RemoveWorkspaceMember:output_type -> openshell.v1.RemoveWorkspaceMemberResponse + 190, // 286: openshell.v1.OpenShell.ListWorkspaceMembers:output_type -> openshell.v1.ListWorkspaceMembersResponse 221, // [221:287] is the sub-list for method output_type 155, // [155:221] is the sub-list for method input_type 155, // [155:155] is the sub-list for extension type_name @@ -14884,8 +14940,8 @@ func file_openshell_proto_init() { (*SandboxStreamEvent_Warning)(nil), (*SandboxStreamEvent_DraftPolicyUpdate)(nil), } - file_openshell_proto_msgTypes[83].OneofWrappers = []any{} - file_openshell_proto_msgTypes[107].OneofWrappers = []any{ + file_openshell_proto_msgTypes[84].OneofWrappers = []any{} + file_openshell_proto_msgTypes[108].OneofWrappers = []any{ (*PolicyMergeOperation_AddRule)(nil), (*PolicyMergeOperation_RemoveEndpoint)(nil), (*PolicyMergeOperation_RemoveRule)(nil), @@ -14893,29 +14949,29 @@ func file_openshell_proto_init() { (*PolicyMergeOperation_AddAllowRules)(nil), (*PolicyMergeOperation_RemoveBinary)(nil), } - file_openshell_proto_msgTypes[126].OneofWrappers = []any{ + file_openshell_proto_msgTypes[127].OneofWrappers = []any{ (*SupervisorMessage_Hello)(nil), (*SupervisorMessage_Heartbeat)(nil), (*SupervisorMessage_RelayOpenResult)(nil), (*SupervisorMessage_RelayClose)(nil), } - file_openshell_proto_msgTypes[127].OneofWrappers = []any{ + file_openshell_proto_msgTypes[128].OneofWrappers = []any{ (*GatewayMessage_SessionAccepted)(nil), (*GatewayMessage_SessionRejected)(nil), (*GatewayMessage_Heartbeat)(nil), (*GatewayMessage_RelayOpen)(nil), (*GatewayMessage_RelayClose)(nil), } - file_openshell_proto_msgTypes[133].OneofWrappers = []any{ + file_openshell_proto_msgTypes[134].OneofWrappers = []any{ (*RelayOpen_Ssh)(nil), (*RelayOpen_Tcp)(nil), } - file_openshell_proto_msgTypes[137].OneofWrappers = []any{ + file_openshell_proto_msgTypes[138].OneofWrappers = []any{ (*RelayFrame_Init)(nil), (*RelayFrame_Data)(nil), } - file_openshell_proto_msgTypes[167].OneofWrappers = []any{} file_openshell_proto_msgTypes[168].OneofWrappers = []any{} + file_openshell_proto_msgTypes[169].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ From 0541d456d41b3937f92b8dba37c51441478529db Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Tue, 18 Aug 2026 18:13:51 -0700 Subject: [PATCH 3/5] fix(providers): migrate legacy refresh secrets before skip Signed-off-by: Mrunal Patel --- .../openshell-server/src/provider_refresh.rs | 81 ++++++++++++++++--- 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index e91e4c2e1d..f75c25241f 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -1634,18 +1634,6 @@ async fn run_refresh_worker_tick( } continue; } - let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) - .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); - if !is_gateway_mintable_strategy(strategy) { - warn!( - provider = %state.provider_name, - credential_key = %state.credential_key, - strategy = %refresh_strategy_name(state.strategy), - status = %state.status, - "skipping non-gateway-mintable provider credential refresh state" - ); - continue; - } let mut state = match migrate_inline_secret_material(store, credentials, &state).await { Ok(state) => state, Err(err) => { @@ -1672,6 +1660,18 @@ async fn run_refresh_worker_tick( "provider refresh material cleanup failed; continuing with live refresh" ); } + let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) + .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); + if !is_gateway_mintable_strategy(strategy) { + warn!( + provider = %state.provider_name, + credential_key = %state.credential_key, + strategy = %refresh_strategy_name(state.strategy), + status = %state.status, + "skipping non-gateway-mintable provider credential refresh state" + ); + continue; + } let due = state.next_refresh_at_ms <= 0 || state.next_refresh_at_ms <= now_ms; let rotation_requested = state.status == "rotation_requested"; info!( @@ -2692,6 +2692,63 @@ mod tests { ); } + #[tokio::test] + async fn refresh_worker_migrates_legacy_secrets_before_skipping_non_mintable_state() { + let store = test_store().await; + let provider = provider("legacy-external", "outlook"); + store.put_message(&provider).await.unwrap(); + let state = new_refresh_state( + &provider, + "default", + "MS_GRAPH_ACCESS_TOKEN", + NewRefreshStateConfig { + strategy: ProviderCredentialRefreshStrategy::External, + material: HashMap::from([( + "legacy_secret".to_string(), + "move-me-out-of-the-database".to_string(), + )]), + secret_material_keys: vec!["legacy_secret".to_string()], + expires_at_ms: 0, + token_url: String::new(), + scopes: Vec::new(), + refresh_before_seconds: 0, + max_lifetime_seconds: 0, + additional_output_keys: HashMap::new(), + }, + ) + .unwrap(); + put_refresh_state(&store, &state).await.unwrap(); + let credentials = test_credentials(); + + run_refresh_worker_tick(&store, Some(&credentials), None) + .await + .unwrap(); + + let stored = get_refresh_state( + &store, + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert!(!stored.material.contains_key("legacy_secret")); + assert!(stored.secret_material_handles.contains_key("legacy_secret")); + assert_eq!(stored.status, "configured"); + assert_eq!( + credentials + .resolve_refresh_material( + refresh_material_scope(&stored), + &stored.secret_material_handles, + ) + .await + .unwrap() + .get("legacy_secret"), + Some(&"move-me-out-of-the-database".to_string()) + ); + } + #[tokio::test] async fn refresh_worker_finalizes_tombstoned_refresh_material() { let store = test_store().await; From 16005c676f057adda8a676306508b03d71924388 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Wed, 19 Aug 2026 08:18:24 -0700 Subject: [PATCH 4/5] refactor(providers): defer credential migration Signed-off-by: Mrunal Patel --- architecture/gateway.md | 5 + .../openshell-server/src/provider_refresh.rs | 253 ++---------------- docs/reference/gateway-config.mdx | 2 +- docs/sandboxes/providers-v2.mdx | 14 +- 4 files changed, 40 insertions(+), 234 deletions(-) diff --git a/architecture/gateway.md b/architecture/gateway.md index 33fd680d75..d2e15f01e6 100644 --- a/architecture/gateway.md +++ b/architecture/gateway.md @@ -335,6 +335,11 @@ Multi-replica deployments can use that default with a shared database and shared key-encryption key, or opt into an external backend such as Vault or Kubernetes Secrets. +Credential handles remain bound to the driver that created them. Before the +0.1.0 compatibility boundary, gateways do not migrate inline refresh material +or move handles between credential drivers; operators reconfigure affected +grants when upgrading or changing backends. + ### Optimistic Concurrency (CAS) Every object row carries a `resource_version` that the database increments diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index f75c25241f..8e39d64880 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -568,85 +568,6 @@ fn validate_secret_material_references( ))) } -async fn migrate_inline_secret_material( - store: &Store, - credentials: Option<&crate::credentials::CredentialRuntime>, - state: &StoredProviderCredentialRefreshState, -) -> Result { - let strategy = ProviderCredentialRefreshStrategy::try_from(state.strategy) - .unwrap_or(ProviderCredentialRefreshStrategy::Unspecified); - let mut secret_keys: std::collections::HashSet = - state.secret_material_keys.iter().cloned().collect(); - secret_keys.extend( - strategy_secret_material_keys(strategy) - .iter() - .map(|key| (*key).to_string()), - ); - let inline_secrets: HashMap = secret_keys - .into_iter() - .filter_map(|key| state.material.get(&key).cloned().map(|value| (key, value))) - .collect(); - if inline_secrets.is_empty() { - return Ok(state.clone()); - } - let Some(credentials) = credentials else { - // Production refresh entry points always supply the server credential - // runtime. Keeping the no-runtime path readable preserves focused unit - // tests and test-only helpers that exercise minting in isolation. - return Ok(state.clone()); - }; - let values_to_stage: HashMap<_, _> = inline_secrets - .iter() - .filter(|(key, _)| !state.secret_material_handles.contains_key(*key)) - .map(|(key, value)| (key.clone(), value.clone())) - .collect(); - let staging_id = format!( - "{}-refresh-migration-{}", - state.object_id(), - uuid::Uuid::new_v4() - ); - let staged = credentials - .store_refresh_material_with_object_id( - refresh_material_scope(state), - &staging_id, - &values_to_stage, - &HashMap::new(), - ) - .await?; - let mut migrated = state.clone(); - migrated.secret_material_handles.extend(staged.clone()); - for key in inline_secrets.keys() { - migrated.material.remove(key); - if !migrated.secret_material_keys.contains(key) { - migrated.secret_material_keys.push(key.clone()); - } - } - migrated.secret_material_keys.sort(); - migrated.secret_material_keys.dedup(); - let expected_version = state - .metadata - .as_ref() - .map_or(0, |metadata| metadata.resource_version); - match persist_refresh_state_if_current(store, &migrated, expected_version).await { - Ok(Some(new_version)) => { - if let Some(metadata) = migrated.metadata.as_mut() { - metadata.resource_version = new_version; - } - Ok(migrated) - } - Ok(None) => { - cleanup_staged_refresh_material_handles(credentials, state, &staged).await; - Err(Status::aborted( - "provider refresh was deleted or superseded during material migration", - )) - } - Err(err) => { - cleanup_staged_refresh_material_handles(credentials, state, &staged).await; - Err(err) - } - } -} - pub async fn refresh_provider_credential( store: &Store, workspace: &str, @@ -674,7 +595,7 @@ pub async fn refresh_provider_credential( "provider refresh is being deleted", )); } - let mut state = migrate_inline_secret_material(store, Some(credentials), &state).await?; + let mut state = state; validate_secret_material_references(&state)?; // Generation of the refresh at the start of the rotation. Terminal persists // match on it so a concurrent delete or rotation is detected rather than @@ -1634,18 +1555,7 @@ async fn run_refresh_worker_tick( } continue; } - let mut state = match migrate_inline_secret_material(store, credentials, &state).await { - Ok(state) => state, - Err(err) => { - warn!( - provider = %state.provider_name, - credential_key = %state.credential_key, - error = %err, - "provider refresh material migration failed" - ); - continue; - } - }; + let mut state = state; let expected_version = state .metadata .as_ref() @@ -1735,9 +1645,9 @@ mod tests { use super::{ NewRefreshStateConfig, delete_refresh_state_with_credentials, effective_authorization_epoch, enqueue_pending_secret_deletion, get_refresh_state, - list_all_refresh_states, list_refresh_states_for_provider, migrate_inline_secret_material, - new_refresh_state, put_refresh_state, refresh_material_scope, refresh_provider_credential, - refresh_state_name, refresh_strategy_name, run_refresh_worker_tick, seconds_until_ms, + list_all_refresh_states, list_refresh_states_for_provider, new_refresh_state, + put_refresh_state, refresh_material_scope, refresh_provider_credential, refresh_state_name, + refresh_strategy_name, run_refresh_worker_tick, seconds_until_ms, validate_secret_material_references, }; use crate::credentials::CredentialRuntime; @@ -1801,76 +1711,6 @@ mod tests { assert_eq!(all[0].metadata.as_ref().unwrap().resource_version, 1); } - #[tokio::test] - async fn superseded_inline_material_migration_cleans_staged_handle() { - let store = test_store().await; - let provider = provider("migration-race", "outlook"); - let state = new_refresh_state( - &provider, - "default", - "MS_GRAPH_ACCESS_TOKEN", - NewRefreshStateConfig { - strategy: ProviderCredentialRefreshStrategy::Oauth2ClientCredentials, - material: HashMap::from([ - ("client_id".to_string(), "client-id".to_string()), - ("client_secret".to_string(), "client-secret".to_string()), - ]), - secret_material_keys: vec!["client_secret".to_string()], - expires_at_ms: 0, - token_url: "https://issuer.example/token".to_string(), - scopes: Vec::new(), - refresh_before_seconds: 30, - max_lifetime_seconds: 60, - additional_output_keys: HashMap::new(), - }, - ) - .unwrap(); - put_refresh_state(&store, &state).await.unwrap(); - let state = get_refresh_state( - &store, - "default", - provider.object_id(), - "MS_GRAPH_ACCESS_TOKEN", - ) - .await - .unwrap() - .unwrap(); - let credentials = test_credentials(); - let (store_hit, release_store) = credentials.gate_next_store(); - - let migration = migrate_inline_secret_material(&store, Some(&credentials), &state); - let supersede = async { - store_hit.await.unwrap(); - let mut winner = get_refresh_state( - &store, - "default", - provider.object_id(), - "MS_GRAPH_ACCESS_TOKEN", - ) - .await - .unwrap() - .unwrap(); - winner.last_error = "won-by-concurrent-writer".to_string(); - put_refresh_state(&store, &winner).await.unwrap(); - release_store.send(()).unwrap(); - }; - let (result, ()) = tokio::join!(migration, supersede); - - assert_eq!(result.unwrap_err().code(), tonic::Code::Aborted); - assert_eq!(credentials.stored_credential_count(), Some(0)); - let winner = get_refresh_state( - &store, - "default", - provider.object_id(), - "MS_GRAPH_ACCESS_TOKEN", - ) - .await - .unwrap() - .unwrap(); - assert_eq!(winner.last_error, "won-by-concurrent-writer"); - assert!(winner.secret_material_handles.is_empty()); - } - #[test] fn new_refresh_configuration_rotates_authorization_epoch_and_legacy_state_is_stable() { let provider = Provider { @@ -2086,7 +1926,7 @@ mod tests { let store = test_store().await; let provider = provider("my-stored-graph", "outlook"); store.put_message(&provider).await.unwrap(); - let state = new_refresh_state( + let mut state = new_refresh_state( &provider, "default", "MS_GRAPH_ACCESS_TOKEN", @@ -2106,10 +1946,20 @@ mod tests { }, ) .unwrap(); - put_refresh_state(&store, &state).await.unwrap(); - let authorization_epoch = state.authorization_epoch.clone(); let config = Config::new(None).with_credential_drivers(["test-static"]); let credentials = CredentialRuntime::from_config(&config).unwrap(); + state.secret_material_handles = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + "configured-client-secret", + &HashMap::from([("client_secret".to_string(), "client-secret".to_string())]), + &HashMap::new(), + ) + .await + .unwrap(); + state.material.remove("client_secret"); + put_refresh_state(&store, &state).await.unwrap(); + let authorization_epoch = state.authorization_epoch.clone(); let refreshed = refresh_provider_credential( &store, @@ -2426,6 +2276,16 @@ mod tests { }, ) .unwrap(); + state.secret_material_handles = credentials + .store_refresh_material_with_object_id( + refresh_material_scope(&state), + "current-refresh-object", + &HashMap::from([("client_secret".to_string(), "client-secret".to_string())]), + &HashMap::new(), + ) + .await + .unwrap(); + state.material.remove("client_secret"); let old = credentials .store_refresh_material_with_object_id( refresh_material_scope(&state), @@ -2692,63 +2552,6 @@ mod tests { ); } - #[tokio::test] - async fn refresh_worker_migrates_legacy_secrets_before_skipping_non_mintable_state() { - let store = test_store().await; - let provider = provider("legacy-external", "outlook"); - store.put_message(&provider).await.unwrap(); - let state = new_refresh_state( - &provider, - "default", - "MS_GRAPH_ACCESS_TOKEN", - NewRefreshStateConfig { - strategy: ProviderCredentialRefreshStrategy::External, - material: HashMap::from([( - "legacy_secret".to_string(), - "move-me-out-of-the-database".to_string(), - )]), - secret_material_keys: vec!["legacy_secret".to_string()], - expires_at_ms: 0, - token_url: String::new(), - scopes: Vec::new(), - refresh_before_seconds: 0, - max_lifetime_seconds: 0, - additional_output_keys: HashMap::new(), - }, - ) - .unwrap(); - put_refresh_state(&store, &state).await.unwrap(); - let credentials = test_credentials(); - - run_refresh_worker_tick(&store, Some(&credentials), None) - .await - .unwrap(); - - let stored = get_refresh_state( - &store, - "default", - provider.object_id(), - "MS_GRAPH_ACCESS_TOKEN", - ) - .await - .unwrap() - .unwrap(); - assert!(!stored.material.contains_key("legacy_secret")); - assert!(stored.secret_material_handles.contains_key("legacy_secret")); - assert_eq!(stored.status, "configured"); - assert_eq!( - credentials - .resolve_refresh_material( - refresh_material_scope(&stored), - &stored.secret_material_handles, - ) - .await - .unwrap() - .get("legacy_secret"), - Some(&"move-me-out-of-the-database".to_string()) - ); - } - #[tokio::test] async fn refresh_worker_finalizes_tombstoned_refresh_material() { let store = test_store().await; diff --git a/docs/reference/gateway-config.mdx b/docs/reference/gateway-config.mdx index 402db6dab4..4f896f50ee 100644 --- a/docs/reference/gateway-config.mdx +++ b/docs/reference/gateway-config.mdx @@ -379,7 +379,7 @@ For `kubernetes-secrets`, `namespace` sets where OpenShell-managed provider Secr For `vault`, `address` points at the Vault service, `mount` and `kv_version` describe the KV engine where OpenShell-managed provider secrets are stored, and `auth_method = "kubernetes"` logs in with the gateway Pod's ServiceAccount token. For local or development validation, use `auth_method = "token_file"` with `token_path = "/path/to/token"`. Do not put literal Vault tokens in TOML. -Provider records that already contain inline database credentials remain readable for upgrade compatibility. New provider create/update requests still submit credential values through the normal API, but the gateway stores those values through the active credential storage path and persists only handles. The refresh worker migrates legacy inline secret refresh material to the same storage path before minting. Stop all older gateway replicas before starting the version that performs this migration; older protobuf runtimes do not preserve the new internal handle fields when they rewrite refresh state. +Provider records that already contain inline database credentials remain readable for upgrade compatibility. New provider create/update requests still submit credential values through the normal API, but the gateway stores those values through the active credential storage path and persists only handles. Before OpenShell 0.1.0, OpenShell does not automatically migrate inline refresh material or credential handles between drivers. Reconfigure refresh grants after an upgrade. Before changing credential drivers, remove affected credentials while the original driver is still available, then select the new driver and create them again. Do not run mixed gateway versions against the same refresh records. For remote credential drivers, set `transport = "uds"` with `socket_path`. Omit `command`, `args`, and `startup_timeout_secs` when another service manager prestarts the driver socket. Keep backend tokens out of TOML; point the driver at mounted token files or native identity mechanisms instead. diff --git a/docs/sandboxes/providers-v2.mdx b/docs/sandboxes/providers-v2.mdx index 9c4315ce42..48170900b2 100644 --- a/docs/sandboxes/providers-v2.mdx +++ b/docs/sandboxes/providers-v2.mdx @@ -625,14 +625,12 @@ The gateway sends a complete host, port, and path binding for every emitted stat Refresh configuration is stored separately from the current injectable credential value. Non-secret refresh configuration remains in the refresh-state record. Secret material is resolved from the active credential driver only while the gateway mints a new short-lived token. The gateway writes the token back through credential storage and updates credential expiry metadata. If an OAuth issuer rotates its refresh token, the gateway stages the replacement through credential storage before committing the refresh generation and removes the previous handle afterward. -On upgrade, the refresh worker migrates legacy inline secret material before it -mints again. For a multi-replica gateway, stop every older replica before the -new version begins migration. A normal mixed-version rolling update is unsafe -because older protobuf runtimes can discard internal handle fields when they -rewrite refresh state. Migration removes plaintext values from current records, -but database backups, SQLite WAL/free pages, and Postgres dead tuples may retain -historical bytes. Rotate the upstream grant and apply the database's retention -or compaction procedure when historical erasure is required. +Before OpenShell 0.1.0, refresh-state and credential-driver migrations are not +supported. Upgrading from a build that stored refresh material inline requires +reconfiguring the refresh grant. To change credential drivers, delete or +reconfigure affected providers while the original driver is still available, +then select the new driver and create the credentials again. Do not run mixed +gateway versions against the same refresh records. Each explicit `refresh configure` call also starts a new gateway-owned authorization epoch. Automatic refresh and `refresh rotate` preserve that epoch, From 547b3f0a475c8d94d9b639c066326602a1f02f42 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Wed, 19 Aug 2026 11:16:53 -0700 Subject: [PATCH 5/5] fix(providers): make refresh configuration atomic Signed-off-by: Mrunal Patel --- .agents/skills/openshell-cli/SKILL.md | 9 +- crates/openshell-server/src/grpc/provider.rs | 123 +++++++++++++++++- .../openshell-server/src/persistence/mod.rs | 32 +++++ .../src/persistence/postgres.rs | 44 +++++++ .../src/persistence/sqlite.rs | 38 ++++++ .../openshell-server/src/persistence/tests.rs | 59 +++++++++ .../openshell-server/src/provider_refresh.rs | 32 +++++ proto/openshell.proto | 5 +- sdk/go/proto/openshellv1/openshell.pb.go | 5 +- 9 files changed, 339 insertions(+), 8 deletions(-) diff --git a/.agents/skills/openshell-cli/SKILL.md b/.agents/skills/openshell-cli/SKILL.md index fcbc5be783..1706a907ef 100644 --- a/.agents/skills/openshell-cli/SKILL.md +++ b/.agents/skills/openshell-cli/SKILL.md @@ -184,9 +184,12 @@ The gateway stores secret refresh material through its active credential driver. With Vault selected, refresh tokens, client secrets, and private keys live in Vault alongside injectable provider credentials; refresh state contains only opaque handles. A credential-backend read or write failure makes refresh fail -closed rather than falling back to inline storage. During an upgrade that -migrates legacy inline refresh material, stop all older gateway replicas before -starting the new version; do not use a mixed-version rolling update. +closed rather than falling back to inline storage. Before OpenShell 0.1.0, the +gateway does not migrate legacy inline refresh material or move secrets between +credential backends. Reconfigure affected grants after upgrading, and remove or +reconfigure credentials while the original backend remains available before +changing backends. Do not run mixed gateway versions against the same refresh +records. Gateway-managed refresh credentials use an identity-stable workload handle. Routine automatic refresh and `provider refresh rotate` update the access token diff --git a/crates/openshell-server/src/grpc/provider.rs b/crates/openshell-server/src/grpc/provider.rs index 6ee17b632c..25bfbb045d 100644 --- a/crates/openshell-server/src/grpc/provider.rs +++ b/crates/openshell-server/src/grpc/provider.rs @@ -3831,7 +3831,7 @@ pub(super) async fn handle_configure_provider_refresh( Err(err) => Err(err), } } else { - crate::provider_refresh::put_refresh_state(state.store.as_ref(), &state_record).await + crate::provider_refresh::create_refresh_state(state.store.as_ref(), &state_record).await }; if let Err(err) = persist_result { if let Err(cleanup_err) = state @@ -6041,6 +6041,127 @@ mod tests { ); } + #[tokio::test(flavor = "multi_thread", worker_threads = 4)] + async fn concurrent_first_refresh_configure_keeps_only_winner_material() { + let first_state = test_server_state().await; + import_test_graph_refresh_profile(&first_state).await; + create_provider_record( + first_state.store.as_ref(), + "default", + Provider { + metadata: Some(openshell_core::proto::datamodel::v1::ObjectMeta { + name: "configure-create-race".to_string(), + workspace: "default".to_string(), + ..Default::default() + }), + r#type: TEST_GRAPH_PROVIDER_TYPE.to_string(), + profile_workspace: "default".to_string(), + ..Default::default() + }, + ) + .await + .unwrap(); + + // Model a second gateway replica: it shares the durable database and + // credential backend, but owns an independent sandbox synchronization + // guard, so process-local serialization cannot hide this race. + let second_state = Arc::new(ServerState::new_with_credentials( + first_state.config.clone(), + Arc::clone(&first_state.store), + crate::compute::new_test_runtime(Arc::clone(&first_state.store)).await, + crate::sandbox_index::SandboxIndex::new(), + crate::sandbox_watch::SandboxWatchBus::new(), + crate::tracing_bus::TracingLogBus::new(), + Arc::new(crate::supervisor_session::SupervisorSessionRegistry::new()), + None, + first_state.credentials.clone(), + )); + let request = |client_secret: &str| ConfigureProviderRefreshRequest { + provider: "configure-create-race".to_string(), + credential_key: "MS_GRAPH_ACCESS_TOKEN".to_string(), + strategy: ProviderCredentialRefreshStrategy::Oauth2ClientCredentials as i32, + material: HashMap::from([ + ("tenant_id".to_string(), "tenant".to_string()), + ("client_id".to_string(), "client-id".to_string()), + ("client_secret".to_string(), client_secret.to_string()), + ]), + secret_material_keys: vec!["client_secret".to_string()], + expires_at_ms: None, + workspace: "default".to_string(), + }; + let (first_store_hit, release_first_store) = first_state.credentials.gate_next_store(); + + let first = handle_configure_provider_refresh( + &first_state, + authed_request(request("loser-secret")), + ); + let second = async { + first_store_hit.await.unwrap(); + let result = handle_configure_provider_refresh( + &second_state, + authed_request(request("winner-secret")), + ) + .await; + release_first_store.send(()).unwrap(); + result + }; + let (first_result, second_result) = tokio::join!(first, second); + + assert_eq!(first_result.unwrap_err().code(), Code::Aborted); + second_result.unwrap(); + assert_eq!(first_state.credentials.stored_credential_count(), Some(1)); + + let provider = first_state + .store + .get_message_by_name::("default", "configure-create-race") + .await + .unwrap() + .unwrap(); + let stored = crate::provider_refresh::get_refresh_state( + first_state.store.as_ref(), + "default", + provider.object_id(), + "MS_GRAPH_ACCESS_TOKEN", + ) + .await + .unwrap() + .unwrap(); + assert_eq!( + first_state + .credentials + .resolve_refresh_material( + crate::provider_refresh::refresh_material_scope(&stored), + &stored.secret_material_handles, + ) + .await + .unwrap() + .get("client_secret"), + Some(&"winner-secret".to_string()) + ); + + let physical = first_state + .store + .get_by_name( + StoredProviderCredentialRefreshState::object_type(), + "default", + stored.object_name(), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(physical.id, stored.object_id()); + assert_eq!( + crate::provider_refresh::list_refresh_states_for_provider( + first_state.store.as_ref(), + provider.object_id(), + ) + .await + .unwrap() + .len(), + 1 + ); + } + async fn state_with_authoritative_profiles_over_default_grants() -> Arc { let state = test_server_state().await; let store = state.store.as_ref(); diff --git a/crates/openshell-server/src/persistence/mod.rs b/crates/openshell-server/src/persistence/mod.rs index 3ad20e1082..516faf4fe4 100644 --- a/crates/openshell-server/src/persistence/mod.rs +++ b/crates/openshell-server/src/persistence/mod.rs @@ -339,6 +339,38 @@ impl Store { )) } + /// Atomically insert a generic named object with an application-owned scope. + /// + /// Unlike [`Self::put_scoped`], this never updates an existing object. A + /// duplicate id or `(object_type, workspace, name)` returns + /// [`PersistenceError::UniqueViolation`]. + #[allow(clippy::too_many_arguments)] + #[tracing::instrument( + name = "store", + skip_all, + fields(otel.name = "store.create_scoped", otel.status_code = tracing::field::Empty, object_type = %object_type, object.id = %id, object.name = %name, workspace = %workspace, scope = %scope) + )] + pub async fn create_scoped( + &self, + object_type: &str, + id: &str, + name: &str, + workspace: &str, + scope: &str, + payload: &[u8], + labels: Option<&str>, + ) -> PersistenceResult { + store_dispatch_traced!(self.create_scoped( + object_type, + id, + name, + workspace, + scope, + payload, + labels + )) + } + /// Fetch an object by id. #[tracing::instrument( name = "store", diff --git a/crates/openshell-server/src/persistence/postgres.rs b/crates/openshell-server/src/persistence/postgres.rs index 9195f5dda4..73039acf05 100644 --- a/crates/openshell-server/src/persistence/postgres.rs +++ b/crates/openshell-server/src/persistence/postgres.rs @@ -293,6 +293,50 @@ ON CONFLICT (object_type, workspace, name) WHERE name IS NOT NULL DO UPDATE SET Ok(()) } + #[allow(clippy::too_many_arguments)] + pub async fn create_scoped( + &self, + object_type: &str, + id: &str, + name: &str, + workspace: &str, + scope: &str, + payload: &[u8], + labels: Option<&str>, + ) -> PersistenceResult { + let now_ms = current_time_ms(); + let labels_jsonb: Option = labels + .map(serde_json::from_str) + .transpose() + .map_err(|e| PersistenceError::Encode(format!("invalid labels JSON: {e}")))?; + + let row = sqlx::query( + r" +INSERT INTO objects (object_type, id, name, workspace, scope, payload, created_at_ms, updated_at_ms, labels, resource_version) +VALUES ($1, $2, $3, $4, $5, $6, $7, $7, COALESCE($8, '{}'::jsonb), 1) +RETURNING resource_version, created_at_ms, updated_at_ms +", + ) + .bind(object_type) + .bind(id) + .bind(name) + .bind(workspace) + .bind(scope) + .bind(payload) + .bind(now_ms) + .bind(labels_jsonb) + .fetch_one(&self.pool) + .await + .map_err(|e| map_db_error(&e))?; + + let resource_version_i64: i64 = row.try_get("resource_version").unwrap_or(1); + Ok(WriteResult { + resource_version: resource_version_i64.max(1).cast_unsigned(), + created_at_ms: row.get("created_at_ms"), + updated_at_ms: row.get("updated_at_ms"), + }) + } + pub async fn get( &self, object_type: &str, diff --git a/crates/openshell-server/src/persistence/sqlite.rs b/crates/openshell-server/src/persistence/sqlite.rs index b54c41e111..b7bff9c2d2 100644 --- a/crates/openshell-server/src/persistence/sqlite.rs +++ b/crates/openshell-server/src/persistence/sqlite.rs @@ -319,6 +319,44 @@ ON CONFLICT ("object_type", "workspace", "name") WHERE "name" IS NOT NULL DO UPD Ok(()) } + #[allow(clippy::too_many_arguments)] + pub async fn create_scoped( + &self, + object_type: &str, + id: &str, + name: &str, + workspace: &str, + scope: &str, + payload: &[u8], + labels: Option<&str>, + ) -> PersistenceResult { + let now_ms = current_time_ms(); + + sqlx::query( + r#" +INSERT INTO "objects" ("object_type", "id", "name", "workspace", "scope", "payload", "created_at_ms", "updated_at_ms", "labels", "resource_version") +VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?7, ?8, 1) +"#, + ) + .bind(object_type) + .bind(id) + .bind(name) + .bind(workspace) + .bind(scope) + .bind(payload) + .bind(now_ms) + .bind(labels.unwrap_or("{}")) + .execute(&self.pool) + .await + .map_err(|e| map_db_error(&e))?; + + Ok(WriteResult { + resource_version: 1, + created_at_ms: now_ms, + updated_at_ms: now_ms, + }) + } + pub async fn get( &self, object_type: &str, diff --git a/crates/openshell-server/src/persistence/tests.rs b/crates/openshell-server/src/persistence/tests.rs index 6227eec297..8802ac8d10 100644 --- a/crates/openshell-server/src/persistence/tests.rs +++ b/crates/openshell-server/src/persistence/tests.rs @@ -1302,6 +1302,65 @@ fn parse_label_selector_handles_whitespace() { assert_eq!(result.get("tier"), Some(&"frontend".to_string())); } +#[tokio::test] +async fn create_scoped_is_insert_only_and_preserves_scope() { + use super::PersistenceError; + + let store = test_store().await; + let created = store + .create_scoped( + "refresh", + "winner-id", + "provider-token", + "default", + "winner-provider", + b"winner", + None, + ) + .await + .unwrap(); + assert_eq!(created.resource_version, 1); + + let duplicate = store + .create_scoped( + "refresh", + "loser-id", + "provider-token", + "default", + "loser-provider", + b"loser", + None, + ) + .await; + assert!(matches!( + duplicate, + Err(PersistenceError::UniqueViolation { .. }) + )); + + let winner = store + .get_by_name("refresh", "default", "provider-token") + .await + .unwrap() + .unwrap(); + assert_eq!(winner.id, "winner-id"); + assert_eq!(winner.payload, b"winner"); + assert_eq!( + store + .list_by_scope("refresh", "winner-provider", 10, 0) + .await + .unwrap() + .len(), + 1 + ); + assert!( + store + .list_by_scope("refresh", "loser-provider", 10, 0) + .await + .unwrap() + .is_empty() + ); +} + // --------------------------------------------------------------------------- // CAS (compare-and-swap) tests // --------------------------------------------------------------------------- diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index 8e39d64880..cb376eadef 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -73,6 +73,7 @@ pub fn effective_authorization_epoch( }) } +#[cfg(test)] pub async fn put_refresh_state( store: &Store, state: &StoredProviderCredentialRefreshState, @@ -83,6 +84,37 @@ pub async fn put_refresh_state( .map_err(|e| Status::internal(format!("persist provider refresh state failed: {e}"))) } +/// Atomically claim a new provider-and-credential refresh identity. +/// +/// The refresh name is unique within a workspace. A concurrent creator must +/// lose instead of overwriting the winner so its caller can delete any secret +/// material staged before this write. +pub async fn create_refresh_state( + store: &Store, + state: &StoredProviderCredentialRefreshState, +) -> Result<(), Status> { + match store + .create_scoped( + StoredProviderCredentialRefreshState::object_type(), + state.object_id(), + state.object_name(), + state.object_workspace(), + &state.provider_id, + &state.encode_to_vec(), + None, + ) + .await + { + Ok(_) => Ok(()), + Err(PersistenceError::UniqueViolation { .. }) => Err(Status::aborted( + "provider refresh was concurrently configured", + )), + Err(err) => Err(Status::internal(format!( + "create provider refresh state failed: {err}" + ))), + } +} + /// Persist an updated refresh state only if the row still exists with the /// generation read at the start of the rotation. /// diff --git a/proto/openshell.proto b/proto/openshell.proto index 2f0c1ae34c..4dd290090d 100644 --- a/proto/openshell.proto +++ b/proto/openshell.proto @@ -1579,8 +1579,9 @@ message StoredProviderCredentialRefreshState { string credential_key = 4; ProviderCredentialRefreshStrategy strategy = 5; map material = 6 [(openshell.options.v1.secret) = true]; - // Material names classified as secret. Their values live in the active - // credential driver and are absent from material after migration. + // Material names classified as secret. Newly configured values live in the + // active credential driver and are absent from material. Legacy inline values + // are not automatically migrated before OpenShell 0.1.0. repeated string secret_material_keys = 7; int64 expires_at_ms = 8; int64 next_refresh_at_ms = 9; diff --git a/sdk/go/proto/openshellv1/openshell.pb.go b/sdk/go/proto/openshellv1/openshell.pb.go index 365929c885..102688df4f 100644 --- a/sdk/go/proto/openshellv1/openshell.pb.go +++ b/sdk/go/proto/openshellv1/openshell.pb.go @@ -5839,8 +5839,9 @@ type StoredProviderCredentialRefreshState struct { CredentialKey string `protobuf:"bytes,4,opt,name=credential_key,json=credentialKey,proto3" json:"credential_key,omitempty"` Strategy ProviderCredentialRefreshStrategy `protobuf:"varint,5,opt,name=strategy,proto3,enum=openshell.v1.ProviderCredentialRefreshStrategy" json:"strategy,omitempty"` Material map[string]string `protobuf:"bytes,6,rep,name=material,proto3" json:"material,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` - // Material names classified as secret. Their values live in the active - // credential driver and are absent from material after migration. + // Material names classified as secret. Newly configured values live in the + // active credential driver and are absent from material. Legacy inline values + // are not automatically migrated before OpenShell 0.1.0. SecretMaterialKeys []string `protobuf:"bytes,7,rep,name=secret_material_keys,json=secretMaterialKeys,proto3" json:"secret_material_keys,omitempty"` ExpiresAtMs int64 `protobuf:"varint,8,opt,name=expires_at_ms,json=expiresAtMs,proto3" json:"expires_at_ms,omitempty"` NextRefreshAtMs int64 `protobuf:"varint,9,opt,name=next_refresh_at_ms,json=nextRefreshAtMs,proto3" json:"next_refresh_at_ms,omitempty"`