first pass of merging in warp (doesn't build)
This commit is contained in:
@@ -19,8 +19,9 @@ thiserror.workspace = true
|
||||
tink-core = "0.3"
|
||||
tink-proto = "0.3"
|
||||
tink-hybrid = "0.3"
|
||||
tracing.workspace = true
|
||||
zeroize = "1.8"
|
||||
galaxyui.workspace = true
|
||||
galaxyui_core.workspace = true
|
||||
galaxy_core.workspace = true
|
||||
galaxy_graphql.workspace = true
|
||||
vec1.workspace = true
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use vec1::Vec1;
|
||||
|
||||
use galaxy_graphql::managed_secrets::{ManagedSecret, ManagedSecretConfig, ManagedSecretType};
|
||||
|
||||
pub use galaxy_graphql::queries::task_secrets::ManagedSecretValue;
|
||||
|
||||
/// An OIDC identity token issued for a task workload.
|
||||
@@ -42,7 +39,7 @@ pub struct ManagedSecretConfigs {
|
||||
pub team_secrets: HashMap<String, ManagedSecretConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum SecretOwner {
|
||||
CurrentUser,
|
||||
Team { team_uid: String },
|
||||
@@ -74,6 +71,13 @@ pub trait ManagedSecretsClient: 'static + Send + Sync {
|
||||
|
||||
async fn list_secrets(&self) -> Result<Vec<ManagedSecret>>;
|
||||
|
||||
/// List managed secrets that authenticate the given harness.
|
||||
/// Returns an empty list for harnesses that do not use auth secrets (e.g. Oz).
|
||||
async fn list_harness_auth_secrets(
|
||||
&self,
|
||||
harness: warp_graphql::ai::AgentHarness,
|
||||
) -> Result<Vec<ManagedSecret>>;
|
||||
|
||||
async fn get_task_secrets(
|
||||
&self,
|
||||
task_id: String,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use std::{io, sync::Once};
|
||||
use std::io;
|
||||
use std::sync::Once;
|
||||
|
||||
use base64::Engine;
|
||||
use galaxy_graphql::managed_secrets::ManagedSecretType;
|
||||
@@ -14,8 +15,9 @@ pub fn init() {
|
||||
INIT.call_once(|| {
|
||||
tink_hybrid::init();
|
||||
|
||||
use hpke_impl::{HpkePrivateKeyManager, HpkePublicKeyManager};
|
||||
use std::sync::Arc;
|
||||
|
||||
use hpke_impl::{HpkePrivateKeyManager, HpkePublicKeyManager};
|
||||
tink_core::registry::register_key_manager(Arc::new(HpkePublicKeyManager::new()))
|
||||
.expect("unable to register HPKE public key manager");
|
||||
tink_core::registry::register_key_manager(Arc::new(HpkePrivateKeyManager::new()))
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
//!
|
||||
//! Supports both encryption (public key manager) and decryption (private key manager).
|
||||
|
||||
use hpke::{
|
||||
Deserializable, OpModeR, OpModeS, Serializable,
|
||||
aead::{AesGcm128, AesGcm256, ChaCha20Poly1305},
|
||||
kdf::HkdfSha256,
|
||||
kem::X25519HkdfSha256,
|
||||
};
|
||||
use rand::{SeedableRng as _, rngs::StdRng};
|
||||
use hpke::aead::{AesGcm128, AesGcm256, ChaCha20Poly1305};
|
||||
use hpke::kdf::HkdfSha256;
|
||||
use hpke::kem::X25519HkdfSha256;
|
||||
use hpke::{Deserializable, OpModeR, OpModeS, Serializable};
|
||||
use rand::SeedableRng as _;
|
||||
use rand::rngs::StdRng;
|
||||
use tink_core::TinkError;
|
||||
use tink_proto::{HpkeAead, HpkeKdf, HpkeKem, prost::Message};
|
||||
use tink_proto::prost::Message;
|
||||
use tink_proto::{HpkeAead, HpkeKdf, HpkeKem};
|
||||
|
||||
pub const HPKE_PUBLIC_KEY_TYPE_URL: &str = "type.googleapis.com/google.crypto.tink.HpkePublicKey";
|
||||
pub const HPKE_PRIVATE_KEY_TYPE_URL: &str = "type.googleapis.com/google.crypto.tink.HpkePrivateKey";
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use std::io;
|
||||
|
||||
use tink_proto::{KeysetInfo, keyset_info::KeyInfo};
|
||||
|
||||
use crate::ManagedSecretValue;
|
||||
use tink_proto::KeysetInfo;
|
||||
use tink_proto::keyset_info::KeyInfo;
|
||||
|
||||
use super::UploadKey;
|
||||
use crate::ManagedSecretValue;
|
||||
|
||||
#[test]
|
||||
fn test_import_public_keyset() {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::OsString,
|
||||
io::Write,
|
||||
path::{Path, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Duration;
|
||||
|
||||
use galaxy_core::safe_debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
use std::{collections::HashMap, future::Future, sync::Arc, time::Duration};
|
||||
use std::collections::HashMap;
|
||||
use std::future::Future;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use vec1::vec1;
|
||||
|
||||
use galaxy_core::features::FeatureFlag;
|
||||
use galaxy_graphql::managed_secrets::ManagedSecret;
|
||||
use galaxyui::{Entity, SingletonEntity};
|
||||
|
||||
use crate::{
|
||||
ManagedSecretValue,
|
||||
client::{
|
||||
IdentityTokenOptions, ManagedSecretConfigs, ManagedSecretsClient, SecretOwner,
|
||||
TaskIdentityToken,
|
||||
},
|
||||
envelope::UploadKey,
|
||||
gcp::{self, GcpWorkloadIdentityFederationError, GcpWorkloadIdentityFederationToken},
|
||||
};
|
||||
use galaxy_graphql::queries::task_secrets::ManagedSecretValue as GqlManagedSecretValue;
|
||||
use galaxyui_core::{Entity, SingletonEntity};
|
||||
|
||||
use crate::ManagedSecretValue;
|
||||
use crate::client::{
|
||||
IdentityTokenOptions, ManagedSecretConfigs, ManagedSecretsClient, SecretOwner,
|
||||
TaskIdentityToken,
|
||||
};
|
||||
use crate::envelope::UploadKey;
|
||||
use crate::gcp::{self, GcpWorkloadIdentityFederationError, GcpWorkloadIdentityFederationToken};
|
||||
|
||||
/// Singleton model for working with Warp-managed secrets.
|
||||
pub struct ManagedSecretManager {
|
||||
@@ -161,8 +161,12 @@ impl ManagedSecretManager {
|
||||
&self,
|
||||
task_id: String,
|
||||
) -> impl Future<Output = anyhow::Result<HashMap<String, ManagedSecretValue>>> + use<> {
|
||||
let client = self.client.clone();
|
||||
async move {
|
||||
// Define and invoke an inner async function to simplify tracing instrumentation.
|
||||
#[tracing::instrument(name = "get_task_secrets", skip_all, err, fields(tags.cloud_agent = true))]
|
||||
async fn inner(
|
||||
client: Arc<dyn ManagedSecretsClient>,
|
||||
task_id: String,
|
||||
) -> anyhow::Result<HashMap<String, ManagedSecretValue>> {
|
||||
// We only need the workload token for the duration of the request.
|
||||
let workload_token =
|
||||
galaxy_isolation_platform::issue_workload_token(Some(Duration::from_mins(5)))
|
||||
@@ -196,6 +200,9 @@ impl ManagedSecretManager {
|
||||
v.aws_region,
|
||||
)
|
||||
}
|
||||
GqlManagedSecretValue::ManagedSecretOpenAiApiKeyValue(v) => {
|
||||
ManagedSecretValue::openai_api_key(v.api_key, v.base_url)
|
||||
}
|
||||
GqlManagedSecretValue::Unknown => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Unknown secret value type for secret: {}",
|
||||
@@ -207,6 +214,8 @@ impl ManagedSecretManager {
|
||||
}
|
||||
Ok(secrets)
|
||||
}
|
||||
|
||||
inner(self.client.clone(), task_id)
|
||||
}
|
||||
|
||||
/// Issue a short-lived OIDC identity token for the current task.
|
||||
|
||||
@@ -26,6 +26,13 @@ pub enum ManagedSecretValue {
|
||||
aws_bearer_token_bedrock: String,
|
||||
aws_region: String,
|
||||
},
|
||||
OpenaiApiKey {
|
||||
api_key: String,
|
||||
/// Optional base URL for the OpenAI API (e.g. regional endpoints).
|
||||
/// When absent, the harness uses the provider's default endpoint.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
base_url: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
impl ManagedSecretValue {
|
||||
@@ -63,6 +70,14 @@ impl ManagedSecretValue {
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct an OpenAI API key secret value with an optional base URL.
|
||||
pub fn openai_api_key(api_key: impl Into<String>, base_url: Option<String>) -> Self {
|
||||
Self::OpenaiApiKey {
|
||||
api_key: api_key.into(),
|
||||
base_url,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn secret_type(&self) -> ManagedSecretType {
|
||||
match self {
|
||||
ManagedSecretValue::RawValue { .. } => ManagedSecretType::RawValue,
|
||||
@@ -73,6 +88,7 @@ impl ManagedSecretValue {
|
||||
ManagedSecretValue::AnthropicBedrockApiKey { .. } => {
|
||||
ManagedSecretType::AnthropicBedrockApiKey
|
||||
}
|
||||
ManagedSecretValue::OpenaiApiKey { .. } => ManagedSecretType::OpenaiApiKey,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +108,9 @@ impl fmt::Debug for ManagedSecretValue {
|
||||
ManagedSecretValue::AnthropicBedrockApiKey { .. } => f
|
||||
.debug_struct("ManagedSecret::AnthropicBedrockApiKey")
|
||||
.finish_non_exhaustive(),
|
||||
ManagedSecretValue::OpenaiApiKey { .. } => f
|
||||
.debug_struct("ManagedSecret::OpenaiApiKey")
|
||||
.finish_non_exhaustive(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user