From 8fb6a21fa2a2be931aafeed009d0c183914af672 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 29 May 2026 08:33:30 -0700 Subject: [PATCH 1/5] Add an agent_id_parent selector to x509pop in spiffe mode Signed-off-by: Kevin Fox --- pkg/server/plugin/nodeattestor/x509pop/x509pop.go | 14 +++++++++++++- .../plugin/nodeattestor/x509pop/x509pop_test.go | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/pkg/server/plugin/nodeattestor/x509pop/x509pop.go b/pkg/server/plugin/nodeattestor/x509pop/x509pop.go index f7c9ec3fac..05e97157b2 100644 --- a/pkg/server/plugin/nodeattestor/x509pop/x509pop.go +++ b/pkg/server/plugin/nodeattestor/x509pop/x509pop.go @@ -313,11 +313,23 @@ func (p *Plugin) Attest(stream nodeattestorv1.NodeAttestor_AttestServer) error { return status.Errorf(codes.Internal, "failed to make spiffe id: %v", err) } + selectors := buildSelectorValues(leaf, chains, sanSelectors) + + if config.mode == "spiffe" { + agentIDStr := spiffeid.String() + + if lastSlash := strings.LastIndex(agentIDStr, "/"); lastSlash != -1 { + parentID := agentIDStr[:lastSlash] + parentID = strings.TrimSuffix(parentID, "/") + selectors = append(selectors, "agent_id_parent:" + parentID) + } + } + return stream.Send(&nodeattestorv1.AttestResponse{ Response: &nodeattestorv1.AttestResponse_AgentAttributes{ AgentAttributes: &nodeattestorv1.AgentAttributes{ SpiffeId: spiffeid.String(), - SelectorValues: buildSelectorValues(leaf, chains, sanSelectors), + SelectorValues: selectors, CanReattest: true, }, }, diff --git a/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go b/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go index 7f40c87fe5..ccbf81ad69 100644 --- a/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go +++ b/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go @@ -182,6 +182,14 @@ func (s *Suite) TestAttestSuccess() { {Type: "x509pop", Value: "san:environment:production"}, {Type: "x509pop", Value: "san:key:path/to/value"}, } + + if tt.desc == "success with spiffe exchange" { + expectedSelectors = append(expectedSelectors, &common.Selector{ + Type: "x509pop", + Value: "agent_id_parent:spiffe://example.org/spire/agent/x509pop", + }) + } + spirecommonutil.SortSelectors(expectedSelectors) spirecommonutil.SortSelectors(result.Selectors) From d2267cf7327a47f2ca046fa8167577203d3957f9 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 29 May 2026 08:40:29 -0700 Subject: [PATCH 2/5] Update docs Signed-off-by: Kevin Fox --- doc/plugin_server_nodeattestor_x509pop.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/plugin_server_nodeattestor_x509pop.md b/doc/plugin_server_nodeattestor_x509pop.md index 2877a13574..e9e72bb660 100644 --- a/doc/plugin_server_nodeattestor_x509pop.md +++ b/doc/plugin_server_nodeattestor_x509pop.md @@ -48,11 +48,12 @@ A sample configuration: ## Selectors | Selector | Example | Description | -|------------------|-------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Common Name | `x509pop:subject:cn:example.org` | The Subject's Common Name (see X.500 Distinguished Names) | -| SHA1 Fingerprint | `x509pop:ca:fingerprint:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33` | The SHA1 fingerprint as a hex string for each cert in the PoP chain, excluding the leaf. | -| SerialNumber | `x509pop:serialnumber:0a1b2c3d4e5f` | The leaf certificate serial number as a lowercase hexadecimal string | -| San | `x509pop:san::` | The san selectors on the leaf certificate. The expected format of the uri san is `x509pop:////`. One selector is exposed per uri san corresponding to x509pop uri scheme. string | +|------------------|-------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Common Name | `x509pop:subject:cn:example.org` | The Subject's Common Name (see X.500 Distinguished Names) | +| SHA1 Fingerprint | `x509pop:ca:fingerprint:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33` | The SHA1 fingerprint as a hex string for each cert in the PoP chain, excluding the leaf. | +| SerialNumber | `x509pop:serialnumber:0a1b2c3d4e5f` | The leaf certificate serial number as a lowercase hexadecimal string | +| San | `x509pop:san::` | The san selectors on the leaf certificate. The expected format of the uri san is `x509pop:////`. One selector is exposed per uri san corresponding to x509pop uri scheme. string | +| agent_id_parent | `x509pop:agent_id_parent:` | When in spiffe mode, the parent id of the chosen agent id. Ex `spiffe://spire/agent/x509pop/spire-identity-exchange/1234` gets `x509pop:agent_id_parent:spiffe://spire/agent/x509pop/spire-identity-exchange` | ## SVID Path Prefix From 6da39709005a1ce01e82ed5028bcbffc946c5265 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 29 May 2026 09:01:02 -0700 Subject: [PATCH 3/5] Fix review issues Signed-off-by: Kevin Fox --- .../plugin/nodeattestor/x509pop/x509pop.go | 2 +- .../nodeattestor/x509pop/x509pop_test.go | 24 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/pkg/server/plugin/nodeattestor/x509pop/x509pop.go b/pkg/server/plugin/nodeattestor/x509pop/x509pop.go index 05e97157b2..7d948c4cf3 100644 --- a/pkg/server/plugin/nodeattestor/x509pop/x509pop.go +++ b/pkg/server/plugin/nodeattestor/x509pop/x509pop.go @@ -321,7 +321,7 @@ func (p *Plugin) Attest(stream nodeattestorv1.NodeAttestor_AttestServer) error { if lastSlash := strings.LastIndex(agentIDStr, "/"); lastSlash != -1 { parentID := agentIDStr[:lastSlash] parentID = strings.TrimSuffix(parentID, "/") - selectors = append(selectors, "agent_id_parent:" + parentID) + selectors = append(selectors, "agent_id_parent:"+parentID) } } diff --git a/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go b/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go index ccbf81ad69..e95f484162 100644 --- a/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go +++ b/pkg/server/plugin/nodeattestor/x509pop/x509pop_test.go @@ -91,11 +91,12 @@ func (s *Suite) SetupTest() { func (s *Suite) TestAttestSuccess() { tests := []struct { - desc string - giveConfig string - expectAgentID string - certs [][]byte - serialnumber string + desc string + giveConfig string + expectAgentID string + certs [][]byte + serialnumber string + expectAgentIDParentSelector bool }{ { desc: "default success (ca_bundle_path)", @@ -126,11 +127,12 @@ func (s *Suite) TestAttestSuccess() { serialnumber: "serialnumber:0a1b2c3d4e5f", }, { - desc: "success with spiffe exchange", - expectAgentID: "spiffe://example.org/spire/agent/x509pop/testhost", - giveConfig: s.createConfigurationModeSPIFFE(""), - certs: s.svidExchange, - serialnumber: "serialnumber:0a1b2c3d4e7f", + desc: "success with spiffe exchange", + expectAgentID: "spiffe://example.org/spire/agent/x509pop/testhost", + giveConfig: s.createConfigurationModeSPIFFE(""), + expectAgentIDParentSelector: true, + certs: s.svidExchange, + serialnumber: "serialnumber:0a1b2c3d4e7f", }, { desc: "success with custom X509pop san selectors", @@ -183,7 +185,7 @@ func (s *Suite) TestAttestSuccess() { {Type: "x509pop", Value: "san:key:path/to/value"}, } - if tt.desc == "success with spiffe exchange" { + if tt.expectAgentIDParentSelector { expectedSelectors = append(expectedSelectors, &common.Selector{ Type: "x509pop", Value: "agent_id_parent:spiffe://example.org/spire/agent/x509pop", From ac412ddac6a575b9a6d01ce9491ed8302bc7aaa0 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 29 May 2026 09:04:21 -0700 Subject: [PATCH 4/5] Fix review issues Signed-off-by: Kevin Fox --- doc/plugin_server_nodeattestor_x509pop.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/plugin_server_nodeattestor_x509pop.md b/doc/plugin_server_nodeattestor_x509pop.md index e9e72bb660..4f720446e8 100644 --- a/doc/plugin_server_nodeattestor_x509pop.md +++ b/doc/plugin_server_nodeattestor_x509pop.md @@ -48,12 +48,12 @@ A sample configuration: ## Selectors | Selector | Example | Description | -|------------------|-------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| Common Name | `x509pop:subject:cn:example.org` | The Subject's Common Name (see X.500 Distinguished Names) | -| SHA1 Fingerprint | `x509pop:ca:fingerprint:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33` | The SHA1 fingerprint as a hex string for each cert in the PoP chain, excluding the leaf. | -| SerialNumber | `x509pop:serialnumber:0a1b2c3d4e5f` | The leaf certificate serial number as a lowercase hexadecimal string | -| San | `x509pop:san::` | The san selectors on the leaf certificate. The expected format of the uri san is `x509pop:////`. One selector is exposed per uri san corresponding to x509pop uri scheme. string | -| agent_id_parent | `x509pop:agent_id_parent:` | When in spiffe mode, the parent id of the chosen agent id. Ex `spiffe://spire/agent/x509pop/spire-identity-exchange/1234` gets `x509pop:agent_id_parent:spiffe://spire/agent/x509pop/spire-identity-exchange` | +|------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Common Name | `x509pop:subject:cn:example.org` | The Subject's Common Name (see X.500 Distinguished Names) | +| SHA1 Fingerprint | `x509pop:ca:fingerprint:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33` | The SHA1 fingerprint as a hex string for each cert in the PoP chain, excluding the leaf. | +| SerialNumber | `x509pop:serialnumber:0a1b2c3d4e5f` | The leaf certificate serial number as a lowercase hexadecimal string | +| San | `x509pop:san::` | The san selectors on the leaf certificate. The expected format of the uri san is `x509pop:////`. One selector is exposed per uri san corresponding to x509pop uri scheme. string | +| agent_id_parent | `x509pop:agent_id_parent:` | When in SPIFFE mode, the parent ID of the selected agent ID. E.g., `spiffe://spire/agent/x509pop/spire-identity-exchange/1234` yields `x509pop:agent_id_parent:spiffe://spire/agent/x509pop/spire-identity-exchange` | ## SVID Path Prefix From f23599414916d8ba8b2656f17cedc62eb17649b4 Mon Sep 17 00:00:00 2001 From: Kevin Fox Date: Fri, 29 May 2026 09:19:10 -0700 Subject: [PATCH 5/5] Fix docs Signed-off-by: Kevin Fox --- doc/plugin_server_nodeattestor_x509pop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plugin_server_nodeattestor_x509pop.md b/doc/plugin_server_nodeattestor_x509pop.md index 4f720446e8..e37c24b49e 100644 --- a/doc/plugin_server_nodeattestor_x509pop.md +++ b/doc/plugin_server_nodeattestor_x509pop.md @@ -47,7 +47,7 @@ A sample configuration: ## Selectors -| Selector | Example | Description | +| Selector | Example | Description | |------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Common Name | `x509pop:subject:cn:example.org` | The Subject's Common Name (see X.500 Distinguished Names) | | SHA1 Fingerprint | `x509pop:ca:fingerprint:0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33` | The SHA1 fingerprint as a hex string for each cert in the PoP chain, excluding the leaf. |