From 9752c7af46fc9d081d8ad5324e7f4382022bb2d9 Mon Sep 17 00:00:00 2001 From: Vitalii Valkov Date: Sun, 9 Aug 2026 20:32:51 +0200 Subject: [PATCH 1/2] deprecate agents.init_image Superseded by the environment's agent_runtime_image_id. Nothing reads it: the orchestrator refuses a workload whose environment names no runtime rather than substituting the agent's own image (agynio/agents-orchestrator, remove the legacy init container). --- proto/agynio/api/agents/v1/agents.proto | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proto/agynio/api/agents/v1/agents.proto b/proto/agynio/api/agents/v1/agents.proto index fbc59c0..b0d414e 100644 --- a/proto/agynio/api/agents/v1/agents.proto +++ b/proto/agynio/api/agents/v1/agents.proto @@ -248,7 +248,10 @@ message Agent { // definition instead of each carrying its own copy. string image = 7 [deprecated = true]; ComputeResources resources = 8 [deprecated = true]; - string init_image = 9; + // Superseded by the environment's agent_runtime_image_id. Nothing reads this: + // the orchestrator refuses a workload whose environment names no runtime + // rather than substituting an agent-supplied image. + string init_image = 9 [deprecated = true]; string organization_id = 10; string nickname = 11; optional string idle_timeout = 12; // Go duration string (e.g., "30s", "5m", "1h"). @@ -281,7 +284,7 @@ message CreateAgentRequest { string image = 6 [deprecated = true]; ComputeResources resources = 7 [deprecated = true]; string organization_id = 8; - string init_image = 9; + string init_image = 9 [deprecated = true]; string nickname = 10; optional string idle_timeout = 11; // Go duration string (e.g., "30s", "5m", "1h"). // Capabilities supported by this agent. Free-form strings (e.g., "privileged", "dind"). @@ -329,7 +332,7 @@ message UpdateAgentRequest { optional string configuration = 6; optional string image = 7 [deprecated = true]; optional ComputeResources resources = 8 [deprecated = true]; - optional string init_image = 9; + optional string init_image = 9 [deprecated = true]; optional string nickname = 10; optional string idle_timeout = 11; // Go duration string (e.g., "30s", "5m", "1h"). // Capabilities replace the existing list; an empty list clears all capabilities. From 35938f1c4a9786fc7175ba78934b4faa69f83f66 Mon Sep 17 00:00:00 2001 From: Vitalii Valkov Date: Mon, 10 Aug 2026 05:01:40 +0200 Subject: [PATCH 2/2] Name an exposure after the entity serving it The Exposure record was agent-shaped -- agent_id, and nothing else -- while sandboxes have exposed ports since they existed. It takes owner_kind and owner_id, matching the generalization runners.Workload already made, plus the organization and the resolved hostname the intercept.v1 config is written from. agent_id stays for agent-instance owners and is marked deprecated; on AddExposureRequest it is accepted and ignored, since the owner is read from the workload record rather than asserted by the caller. The owner-kind enum is restated here rather than imported from runners: domain packages in this module do not depend on one another, and the values match so neither side needs translating. --- proto/agynio/api/expose/v1/expose.proto | 43 ++++++++++++++++++++----- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/proto/agynio/api/expose/v1/expose.proto b/proto/agynio/api/expose/v1/expose.proto index 7416ae5..93a48e0 100644 --- a/proto/agynio/api/expose/v1/expose.proto +++ b/proto/agynio/api/expose/v1/expose.proto @@ -7,17 +7,18 @@ import "google/protobuf/timestamp.proto"; option go_package = "github.com/agynio/api/gen/agynio/api/expose/v1;exposev1"; // ExposeService manages the lifecycle of port exposures — making ports inside -// agent containers accessible over the OpenZiti network. +// a workload accessible over the OpenZiti network. service ExposeService { - // Expose a port on an agent workload. Creates OpenZiti resources and returns - // the exposure record (including the access URL). + // Expose a port on a workload. Creates OpenZiti resources and returns the + // exposure record (including the access URL). Idempotent per + // (workload_id, port): a port already exposed returns its existing record. rpc AddExposure(AddExposureRequest) returns (AddExposureResponse); - // Un-expose a port on an agent workload. Deletes the OpenZiti resources and - // the exposure record. + // Un-expose a port on a workload. Deletes the OpenZiti resources and the + // exposure record. rpc RemoveExposure(RemoveExposureRequest) returns (RemoveExposureResponse); - // List active exposures for an agent workload. + // List active exposures for a workload. rpc ListExposures(ListExposuresRequest) returns (ListExposuresResponse); } @@ -33,6 +34,15 @@ enum ExposureStatus { EXPOSURE_STATUS_REMOVING = 4; } +// What kind of entity the exposing workload runs for. Mirrors +// agynio.api.runners.v1.RuntimeOwnerKind by value; domain packages do not +// import one another. +enum ExposureOwnerKind { + EXPOSURE_OWNER_KIND_UNSPECIFIED = 0; + EXPOSURE_OWNER_KIND_AGENT_INSTANCE = 1; + EXPOSURE_OWNER_KIND_SANDBOX = 2; +} + // =========================================================================== // Common // =========================================================================== @@ -50,13 +60,26 @@ message EntityMeta { message Exposure { EntityMeta meta = 1; string workload_id = 2; - string agent_id = 3; + // Deprecated: read owner_kind and owner_id instead. Still populated for + // agent-instance-owned exposures; always empty for sandbox-owned ones. + string agent_id = 3 [deprecated = true]; int32 port = 4; string openziti_service_id = 5; string openziti_bind_policy_id = 6; string openziti_dial_policy_id = 7; + // Access URL: http://:. string url = 8; ExposureStatus status = 9; + ExposureOwnerKind owner_kind = 10; + // Agent instance or sandbox the exposing workload runs for. Names the + // exposure — see the hostname field. + string owner_id = 11; + string organization_id = 12; + // Resolved intercept address, e.g. super-sandbox.acme.agyn. Derived from the + // owner and its organization at creation, re-derived by reconciliation, and + // written into the service's intercept.v1 config. Falls back to + // exposed-.agyn when no readable form can be derived. + string hostname = 13; } // =========================================================================== @@ -64,9 +87,13 @@ message Exposure { // =========================================================================== message AddExposureRequest { + // Cluster admins only. Omitted on the standard path, where the workload is + // read from the x-workload-id header the Gateway injects. string workload_id = 1; int32 port = 2; - string agent_id = 3; + // Deprecated: the owner is resolved from the workload record. Accepted and + // ignored. + string agent_id = 3 [deprecated = true]; } message AddExposureResponse {