Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions cli/golem-cli/src/model/text/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,17 @@ impl TextView for PublicOplogEntry {
format_id(&params.name)
));
}
PublicOplogEntry::CardRevoked(params) => {
logln(format_message_highlight("CARD REVOKED"));
logln(format!(
"{pad}at: {}",
format_id(&params.timestamp)
));
logln(format!(
"{pad}card id: {}",
format_id(&params.card_id)
));
}
}
}
}
Expand Down
14 changes: 12 additions & 2 deletions cli/golem-cli/wit/deps/golem-1.x/golem-oplog.wit
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ interface oplog {
name: string,
}

/// Parameters for a card-revoked oplog entry.
record card-revoked-parameters {
timestamp: datetime,
card-id: uuid,
}

record end-atomic-region-parameters {
timestamp: datetime,
begin-index: oplog-index
Expand Down Expand Up @@ -716,7 +722,9 @@ interface oplog {
/// Sets or overwrites a named retry policy
set-retry-policy(set-retry-policy-parameters),
/// Removes a named retry policy by name
remove-retry-policy(remove-retry-policy-parameters)
remove-retry-policy(remove-retry-policy-parameters),
/// Records that a permission card used by the agent has been revoked
card-revoked(card-revoked-parameters)
}

variant public-oplog-entry {
Expand Down Expand Up @@ -810,7 +818,9 @@ interface oplog {
/// Sets or overwrites a named retry policy
set-retry-policy(set-retry-policy-parameters),
/// Removes a named retry policy by name
remove-retry-policy(remove-retry-policy-parameters)
remove-retry-policy(remove-retry-policy-parameters),
/// Records that a permission card used by the agent has been revoked
card-revoked(card-revoked-parameters)
}

/// Enriches raw oplog entries into public oplog entries by resolving oplog payloads
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ message ComponentMetadata {
optional string root_package_version = 7;
repeated golem.schema.AgentTypeSchema agent_types = 8;
map<string, golem.component.AgentTypeProvisionConfig> agent_type_provision_configs = 9;
map<string, bytes> agent_type_initial_permissions = 11;
}
18 changes: 18 additions & 0 deletions golem-api-grpc/proto/golem/registry/v1/registry_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ service RegistryService {
rpc GetResourceDefinitionById (GetResourceDefinitionByIdRequest) returns (GetResourceDefinitionByIdResponse);
rpc GetResourceDefinitionByName (GetResourceDefinitionByNameRequest) returns (GetResourceDefinitionByNameResponse);

// cards api
rpc BatchGetExistingCards (BatchGetExistingCardsRequest) returns (BatchGetExistingCardsResponse);

// registry invalidation stream — multiplexed event types
rpc SubscribeRegistryInvalidations(SubscribeRegistryInvalidationsRequest)
returns (stream RegistryInvalidationEvent);
Expand Down Expand Up @@ -116,6 +119,21 @@ message BatchUpdateResourceUsageSuccessResponse {
golem.common.AccountResourceLimits account_resource_limits = 1;
}

message BatchGetExistingCardsRequest {
repeated golem.common.UUID card_ids = 1;
}

message BatchGetExistingCardsResponse {
oneof result {
BatchGetExistingCardsSuccessResponse success = 1;
RegistryServiceError error = 2;
}
}

message BatchGetExistingCardsSuccessResponse {
repeated golem.common.UUID card_ids = 1;
}

message DownloadComponentRequest {
golem.component.ComponentId componentId = 1;
uint64 revision = 2;
Expand Down
6 changes: 6 additions & 0 deletions golem-api-grpc/proto/golem/worker/public_oplog.proto
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ message OplogEntry {
StartParameters Start = 44;
EndParameters End = 45;
CancelledParameters Cancelled = 46;
CardRevokedParameters CardRevoked = 47;
}
}

Expand Down Expand Up @@ -275,6 +276,11 @@ message RemoveRetryPolicyParameters {
string policy_name = 2;
}

message CardRevokedParameters {
google.protobuf.Timestamp timestamp = 1;
golem.common.UUID card_id = 2;
}

message EndAtomicRegionParameters {
google.protobuf.Timestamp timestamp = 1;
uint64 begin_index = 2;
Expand Down
5 changes: 5 additions & 0 deletions golem-api-grpc/proto/golem/worker/raw_oplog.proto
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ message RawOplogEntry {
RawStartParameters start = 43;
RawEndParameters end = 44;
RawCancelledParameters cancelled = 45;
RawCardRevokedParameters card_revoked = 46;
}
}

Expand Down Expand Up @@ -311,6 +312,10 @@ message RawRemoveRetryPolicyParameters {
string name = 1;
}

message RawCardRevokedParameters {
golem.common.UUID card_id = 1;
}

message RawOplogEntryWithIndex {
uint64 oplog_index = 1;
RawOplogEntry entry = 2;
Expand Down
71 changes: 68 additions & 3 deletions golem-common/src/base_model/card/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use super::{
PermissionPattern, PolymorphicManifestPermissionPattern, PolymorphicPermissionPattern,
};
use crate::base_model::account::AccountId;
use crate::base_model::agent::AgentTypeName;
use crate::base_model::component::{ComponentId, ComponentRevision};
use crate::base_model::environment::EnvironmentId;
use crate::{declare_revision, newtype_uuid};
use chrono::{DateTime, Utc};
Expand All @@ -29,9 +31,20 @@ declare_revision!(CardRevision);
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "full", derive(desert_rust::BinaryCodec))]
pub enum CardManagedBy {
AccountRoot { account_id: AccountId },
EnvironmentDefault { environment_id: EnvironmentId },
PermissionShare { permission_share_id: Uuid },
AccountRoot {
account_id: AccountId,
},
EnvironmentDefault {
environment_id: EnvironmentId,
},
PermissionShare {
permission_share_id: Uuid,
},
AgentInitial {
component_id: ComponentId,
component_revision: ComponentRevision,
agent_type: AgentTypeName,
},
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
Expand All @@ -50,6 +63,7 @@ pub struct Card {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "full", derive(desert_rust::BinaryCodec))]
pub struct PolymorphicCard {
pub card_id: CardId,
pub parent_ids: Vec<CardId>,
Expand All @@ -62,6 +76,57 @@ pub struct PolymorphicCard {
pub system_card: bool,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "full", derive(desert_rust::BinaryCodec))]
pub enum StoredCard {
Concrete(Card),
Polymorphic(PolymorphicCard),
}

impl StoredCard {
pub fn card_id(&self) -> CardId {
match self {
Self::Concrete(card) => card.card_id,
Self::Polymorphic(card) => card.card_id,
}
}

pub fn parent_ids(&self) -> &[CardId] {
match self {
Self::Concrete(card) => &card.parent_ids,
Self::Polymorphic(card) => &card.parent_ids,
}
}

pub fn expires_at(&self) -> Option<DateTime<Utc>> {
match self {
Self::Concrete(card) => card.expires_at,
Self::Polymorphic(card) => card.expires_at,
}
}

pub fn system_card(&self) -> bool {
match self {
Self::Concrete(card) => card.system_card,
Self::Polymorphic(card) => card.system_card,
}
}

pub fn into_concrete(self) -> Result<Card, Self> {
match self {
Self::Concrete(card) => Ok(card),
other => Err(other),
}
}

pub fn into_polymorphic(self) -> Result<PolymorphicCard, Self> {
match self {
Self::Polymorphic(card) => Ok(card),
other => Err(other),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PolymorphicManifestCard {
pub card_id: CardId,
Expand Down
2 changes: 2 additions & 0 deletions golem-common/src/base_model/component_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use crate::base_model::component::{InitialAgentFile, InstalledPlugin};
use crate::base_model::worker::TypedAgentConfigEntry;
use crate::model::agent::AgentTypeName;
use crate::model::card::CardId;
use crate::model::card::PolymorphicPermissionPattern;
use crate::schema::AgentTypeSchema;
use serde::{Deserialize, Serialize, Serializer};
Expand Down Expand Up @@ -204,6 +205,7 @@ pub struct ComponentMetadataInnerData {
#[cfg_attr(feature = "full", desert(evolution()))]
#[serde(rename_all = "camelCase")]
pub struct AgentInitialPermissionTemplate {
pub card_id: CardId,
#[serde(default)]
pub lower_positive: Vec<PolymorphicPermissionPattern>,
#[serde(default)]
Expand Down
12 changes: 12 additions & 0 deletions golem-common/src/base_model/oplog/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -667,5 +667,17 @@ oplog_entry! {
public {
name: String,
}
},
/// Records that a permission card used by the agent has been revoked.
CardRevoked {
hint: true
wit_raw_type: "card-revoked-parameters"
wit_public_type: "card-revoked-parameters"
raw {
card_id: Uuid,
}
public {
card_id: Uuid,
}
}
}
58 changes: 57 additions & 1 deletion golem-common/src/model/component_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ impl ComponentMetadata {
self.data.agent_type_initial_permissions.get(name)
}

pub fn agent_type_initial_permission_templates(
&self,
) -> &BTreeMap<AgentTypeName, AgentInitialPermissionTemplate> {
&self.data.agent_type_initial_permissions
}

pub fn agent_type_env(&self, name: &AgentTypeName) -> Option<&BTreeMap<String, String>> {
self.agent_type_provision_config(name)
.map(|config| &config.env)
Expand Down Expand Up @@ -496,6 +502,7 @@ impl AgentInitialPermissionTemplate {
) -> Self {
let recipient = RecipientPattern::Any;
Self {
card_id: crate::model::card::CardId::new(),
lower_positive: vec![
PolymorphicPermissionPattern::Environment(PolymorphicClassPermissionPattern {
owner: PolymorphicEnvironmentOwnerPattern::Env,
Expand Down Expand Up @@ -749,7 +756,14 @@ mod protobuf {
.map(|config| (AgentTypeName(k), config))
})
.collect::<Result<_, _>>()?,
agent_type_initial_permissions: std::collections::BTreeMap::new(),
agent_type_initial_permissions: value
.agent_type_initial_permissions
.into_iter()
.map(|(k, v)| {
crate::serialization::deserialize(&v)
.map(|template| (AgentTypeName(k), template))
})
.collect::<Result<_, _>>()?,
})
}
}
Expand Down Expand Up @@ -813,6 +827,15 @@ mod protobuf {
)
})
.collect(),
agent_type_initial_permissions: value
.agent_type_initial_permissions
.into_iter()
.map(|(k, v)| {
crate::serialization::serialize(&v)
.map(|template| (k.0, template))
.expect("failed to serialize agent initial permission template")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this acceptable here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The component-metadata cards are just placeholders until they are properly passing in through the api and put into the AgentProvisionConfig. So I would like to leave it like this here

})
.collect(),
}
}
}
Expand Down Expand Up @@ -891,6 +914,10 @@ mod protobuf {
mod tests {
use super::*;
use crate::component_introspection::{ExportedInstance, TopLevelExport};
use crate::model::agent::AgentTypeName;
use crate::model::card::CardId;
use crate::model::component::ComponentName;
use crate::model::environment::EnvironmentName;
use test_r::test;

fn instance_export(name: &str) -> TopLevelExport {
Expand Down Expand Up @@ -974,4 +1001,33 @@ mod tests {
Some("golem:api/oplog-processor@1.5.0.{process}".to_string())
);
}

#[test]
fn component_metadata_grpc_roundtrip_preserves_agent_initial_permissions() {
let agent_type = AgentTypeName("Cart".to_string());
let card_id = CardId::new();
let mut template = AgentInitialPermissionTemplate::default_for(
&EnvironmentName::try_from("prod").unwrap(),
&ComponentName("cart-svc".to_string()),
);
template.card_id = card_id;

let metadata = ComponentMetadata::from_parts(
KnownExports::default(),
Vec::new(),
None,
None,
Vec::new(),
BTreeMap::new(),
)
.with_agent_initial_permissions(BTreeMap::from([(agent_type.clone(), template.clone())]));

let proto: golem_api_grpc::proto::golem::component::ComponentMetadata = metadata.into();
let decoded = ComponentMetadata::try_from(proto).unwrap();

assert_eq!(
decoded.agent_type_initial_permission_template(&agent_type),
Some(&template)
);
}
}
3 changes: 3 additions & 0 deletions golem-common/src/model/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ use crate::base_model::agent::Principal;
use crate::base_model::environment_plugin_grant::EnvironmentPluginGrantId;
use crate::model::account::{AccountEmail, AccountId};
use crate::model::agent::{AgentTypeSchemaResolver, ParsedAgentId};
use crate::model::card::CardId;
use crate::model::invocation_context::InvocationContextStack;
use crate::model::oplog::types::AgentMetadataForGuests;
use crate::model::oplog::{AgentResourceId, OplogEntry, RawSnapshotData};
Expand Down Expand Up @@ -685,6 +686,7 @@ pub struct AgentStatusRecord {
pub active_plugins: HashSet<EnvironmentPluginGrantId>,
pub oplog_processor_checkpoints:
HashMap<EnvironmentPluginGrantId, OplogProcessorCheckpointState>,
pub revoked_cards: HashSet<CardId>,
pub deleted_regions: DeletedRegions,
/// The component version at the starting point of the replay. Will be the version of the Create oplog entry
/// if only automatic updates were used or the version of the latest snapshot-based update
Expand Down Expand Up @@ -728,6 +730,7 @@ impl Default for AgentStatusRecord {
oplog_idx: OplogIndex::default(),
active_plugins: HashSet::new(),
oplog_processor_checkpoints: HashMap::new(),
revoked_cards: HashSet::new(),
deleted_regions: DeletedRegions::new(),
component_revision_for_replay: ComponentRevision::INITIAL,
current_retry_state: HashMap::new(),
Expand Down
5 changes: 5 additions & 0 deletions golem-common/src/model/oplog/matcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,11 @@ impl PublicOplogEntry {
Self::string_match("removeretrypolicy", &[], query_path, query)
|| Self::string_match("remove-retry-policy", &[], query_path, query)
}
PublicOplogEntry::CardRevoked(params) => {
Self::string_match("cardrevoked", &[], query_path, query)
|| Self::string_match("card-revoked", &[], query_path, query)
|| Self::string_match(&params.card_id.to_string(), &[], query_path, query)
}
}
}

Expand Down
Loading
Loading