Repository navigation
ateom/actor ID split: Ateom uses MintAteomActorCertificate - #1809
Conversation
215fc57 to
b913933
Compare
| return nil | ||
| } | ||
| actor, err := resources.ActorRefFromSPIFFEID(actorSpiffeID) | ||
| actor, err := resources.ActorRefFromActorSPIFFEID(actorSpiffeID) |
There was a problem hiding this comment.
Does this need to use ActorRefFromAteomForActorSPIFFEID? My understanding is that the actorSpiffeID here is the one we constructed with AteomForActorSPIFFEID in egress/credentials.go and passed to FetchSecret.
There was a problem hiding this comment.
Hmmmm. I think this field logically should be the actor SPIFFE ID, not the ateom-for-actor SPIFFE ID. This might mean we need to rewrite the URI in the egress gateway: once we authenticate the incoming ateom-for-actor certificate, construct the correct actor SPIFFE ID.
There was a problem hiding this comment.
I've made the necessary adjustments.
Egress parses the ateom-for-actor SPIFFE ID from the incoming connection into an ActorRef, then flattens it back to a plain actor SPIFFE ID when calling plugins (because they care about the actor identity, not the ateom identity).
| func ActorRefFromActorSPIFFEID(id string) (ActorRef, error) { | ||
| u, err := url.Parse(id) | ||
| if err != nil { | ||
| return ActorRef{}, fmt.Errorf("invalid actor SPIFFE ID %q: %w", id, err) | ||
| } | ||
| return ActorRefFromActorSPIFFEURL(u) | ||
| } | ||
|
|
||
| func ActorRefFromActorSPIFFEURL(u *url.URL) (ActorRef, error) { | ||
| if u.Scheme != "spiffe" || u.Host != ActorSPIFFETrustDomain || u.User != nil || u.RawQuery != "" || u.Fragment != "" { | ||
| return ActorRef{}, fmt.Errorf("%q does not have format spiffe://<trust.domain>/actor/<atespace>/<name>", u.String()) | ||
| } | ||
| segments := strings.Split(strings.TrimPrefix(u.Path, "/"), "/") | ||
| if len(segments) != 3 || segments[0] != "actor" { | ||
| return ActorRef{}, fmt.Errorf("%q does not have format spiffe://<trust.domain>/actor/<atespace>/<name>", u.String()) | ||
| } | ||
| atespace, name := segments[1], segments[2] | ||
| if !IsValidResourceName(atespace) { | ||
| return ActorRef{}, fmt.Errorf("%q is not a valid atespace", atespace) | ||
| } | ||
| if !IsValidResourceName(name) { | ||
| return ActorRef{}, fmt.Errorf("%q is not a valid actor name", name) | ||
| } | ||
| return ActorRef{Atespace: atespace, Name: name}, nil | ||
| } |
There was a problem hiding this comment.
Should we add tests for these?
There was a problem hiding this comment.
Done.
| Scheme: "spiffe", | ||
| Host: "substrate-actor.local", | ||
| Path: path.Join("atespace", identity.Atespace, "actor", identity.ActorName), | ||
| Path: path.Join("ateom", "actor", atespace, actorName), |
There was a problem hiding this comment.
IIUC the new ateom for actor cert identifier format is "ateom-for-actor/Atespace/Name", do we need to update that here?
Also not sure how the tests are passing here while the "wrong" format is being used.
There was a problem hiding this comment.
Yup, let me investigate why they are passing.
There was a problem hiding this comment.
The SPIFFE ID is only used in a context where it is supposed to point at an invalid actor.
56938cb to
2737afd
Compare
| if !strings.Contains(line.text, actorName) { | ||
| t.Logf("Log line does not contain %s, discarding", actorName) | ||
| continue | ||
| } | ||
| t.Logf("Considering log line: %s", line.text) | ||
| authority, ok := accessLogField(line.text, "authority") | ||
| if ok && strings.HasSuffix(authority, ":"+port) && strings.Contains(line.text, "/actor/"+actorName) { | ||
| t.Logf("egress gateway tunneled the request: %s", line.text) | ||
| return true | ||
| if !ok { | ||
| t.Logf("Log line does not have an authority field, discarding") | ||
| continue | ||
| } | ||
| if !strings.HasSuffix(authority, ":"+port) { | ||
| t.Logf("Authority does not contain %s, discarding", ":"+port) | ||
| continue | ||
| } | ||
| spiffeSlug := "/ateom-for-actor/" + atespace + "/" + actorName | ||
| if !strings.Contains(line.text, spiffeSlug) { | ||
| t.Logf("Log line does not contain %q, discarding", spiffeSlug) | ||
| continue | ||
| } | ||
| t.Logf("Log line matches") |
There was a problem hiding this comment.
Looks like some of these logs might be for debugging tests, are they all useful or should we trim them down?
There was a problem hiding this comment.
Thanks, trimmed
8d6be5f
…nt-substrate#1810) The purpose field in MintActorCertificate (and the certs it issues) is no longer needed. The distinction between actors and ateoms-for-actors is now built into the SPIFFE URI. Stacked over agent-substrate#1809
Substrate's ateom/actor identity split in agent-substrate/substrate#1809 removed the certificate extension that agentgateway used to authorize egress. It also changed the actor SPIFFE URI expected by credential providers, so both CONNECT authorization and credential injection broke. This PR reads the single `spiffe://substrate-actor.local/ateom-for-actor/<atespace>/<actor>` URI from the authenticated certificate and keeps the `GetActor` check that the actor exists and is running. The UID now comes from `GetActor` for logging. Credential providers receive `spiffe://substrate-actor.local/actor/<atespace>/<actor>`. AI assistance: Codex prepared the implementation, tests, code comments, and this draft description. - [x] As required by the [Code of Conduct](https://github.com/agentgateway/agentgateway/blob/main/CODE_OF_CONDUCT.md#generative-ai-policy), the description, docs, and comments (words meant for humans) are written by a human, not by an LLM. Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
…ess gateway The agentgateway line's 2.3.0 is its re-pin onto upstream v1.6.0 (ea560864): the egress gateway authorizes from the spiffe://substrate-actor.local/ateom-for-actor/<atespace>/<actor> URI that kagent-dev/substrate v0.3.0-alpha3's ateom presents (agent-substrate#1809, agentgateway#3677), which 2.2.2 refuses. Upstream's chart pins the same build as ghcr.io/kagent-dev/substrate/agentgateway:50999825cb55 (agentgateway#3689). The chart default and the CircleCI agentgateway-image parameter move together.
Update atelet/ateom/atunnel to use the new MintAteomActorCertificate, and correct anything that was coded to expect the old actor SPIFFE URI.