first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+2 -1
View File
@@ -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
+9 -5
View File
@@ -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,
+4 -2
View File
@@ -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";
+3 -3
View File
@@ -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() {
+5 -7
View File
@@ -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};
+24 -15
View File
@@ -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(),
}
}
}