🌱 Migrate identity binding and signature verification to exclusive targetRef - #178
Merged
Merged
Conversation
1 task
kevincogan
force-pushed
the
refactor/targetref-migration
branch
from
February 17, 2026 00:10
28189e6 to
e221bd3
Compare
…usive targetRef Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
kevincogan
force-pushed
the
refactor/targetref-migration
branch
from
February 17, 2026 00:48
e221bd3 to
6356040
Compare
kevincogan
marked this pull request as ready for review
February 17, 2026 00:50
…ation - Remove redundant Error field from VerificationResult; callers now use the returned error for infrastructure failures and Details for crypto outcomes (contract documented on the struct) - Add minimum RSA key size enforcement (2048 bits) in VerifyJWS, protecting both Secret and JWKS provider paths - JWKS provider: add singleflight to prevent thundering herd on cache expiry, rate-limit forced refreshes (30s cooldown) to block kid-spray attacks, cap response body at 1 MiB, warn on non-HTTPS endpoints - Secret provider: warn when brute-force fallback iterates >10 keys, add security comment about not logging key material - Metrics: use Register instead of MustRegister to avoid panics when the package is imported from multiple test suites - Improve comments throughout (provider contract, algorithm helpers, canonical JSON, curve validation) Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
- Add recursive _strip_empty() to match Go's removeEmptyFields behavior for nested structures (capabilities, skills), replacing the shallow dict comprehension that could produce signing mismatches - Document ECDSA DER vs raw R||S format difference and the Go verifier's fallback behavior - Improve docstrings: note unencrypted-only PEM requirement, add vault recommendation for production key storage - Update argparse help text to reference docstring Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
Add indexers.go with a sync.Once-guarded field indexer on .spec.targetRef.name. All three controllers (AgentCard, NetworkPolicy, Sync) can register the same index safely — only the first call performs the registration; subsequent calls are no-ops. This replaces full-namespace AgentCard list calls with indexed lookups, reducing reconcile overhead in namespaces with many AgentCards. Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
- Extract propagateLabelToWorkload generic helper, replacing duplicated Deployment/StatefulSet label propagation code - Make updateCondition return error instead of silently swallowing it - Move binding event emission to updateAgentCardStatus with state- transition detection to avoid flooding the event stream on every reconcile cycle; emit AllowlistOnly warning once on first evaluation - Add defensive guard for empty allowedSpiffeIDs (bypassed CRD validation) - Fix StatefulSet readiness check: require readyReplicas > 0 so a StatefulSet scaled to 0 is not considered ready - Use field indexer for workload→AgentCard mapping instead of listing all cards in the namespace - Reduce Reconcile entry log to V(1) to cut noise in production - Improve getServicePort: log when falling back to default port 8000 - Add computeCardId comment clarifying it is NOT for JWS signing Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
…olicy - Extract upsertNetworkPolicy shared helper that handles create-or-update logic with owner references, replacing ~100 lines of duplication between createPermissivePolicy and createRestrictivePolicy - Extract dnsEgressPorts helper for the repeated UDP+TCP port 53 spec - createPermissivePolicy and createRestrictivePolicy now build only the NetworkPolicySpec and delegate persistence to upsertNetworkPolicy - Use field indexer for workload→AgentCard mapping - Consider SignatureIdentityMatch for policy decisions when identity binding is configured (both signature + binding must pass) - Improve deletion: prefer spec.targetRef over status.targetRef, warn on divergence Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
Remove ReconcileAgent, shouldSyncAgent, getAgentCardName, cleanupOrphanedCards, hasOwnerReference, and the agentReconcilerAdapter that supported auto-syncing AgentCards from the legacy Agent CRD. The Agent CRD path is fully superseded by targetRef-based AgentCard creation via Deployment/StatefulSet watchers. Also: - Remove Agent RBAC marker (no longer needed) - Use field indexer for duplicate-card detection in findExistingCardForWorkload - Reduce reconcile entry logs to V(1) - Add isOwnedByAgentCRD TODO noting it can be removed once Agent CRD is fully retired - Remove corresponding Agent CRD tests from agentcardsync_controller_test.go Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
- Inject agentcard.NewFetcher() into AgentCardReconciler so card fetching works out of the box (was previously nil) - Log a startup warning when --require-a2a-signature is false, since identity binding requires signature verification to function Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
Verifier tests (verifier_test.go): - TestCanonicalJSON_BoolFalse_Preserved: bool(false) must not be stripped - TestCanonicalJSON_NestedEmptyFields: nested empty maps/slices removed - TestCanonicalJSON_ExportedVsInternal: exported wrapper matches internal - TestVerifyJWS_RSA_KeyTooSmall: reject 1024-bit RSA keys - TestVerifyJWS_AlgorithmConfusion_RSAKeyWithES256: block alg confusion - TestVerifyJWS_AlgorithmConfusion_ECKeyWithRS256: block alg confusion - TestVerifyJWS_RSAPSS_PS256: verify RSA-PSS signatures - TestVerifyJWS_ECDSA_RawRS_Format: verify raw R||S ECDSA format Controller tests: - Add getServicePort tests (multi-port, single-port, fallback) - Add multi-entry allowlist binding test - Add empty allowedSpiffeIDs defensive guard test - Refactor buildTestJWS to use signature.CreateCanonicalCardJSON instead of maintaining a parallel canonical JSON implementation - Remove duplicated removeEmptyFieldsTest/marshalCanonicalTest helpers Integration tests: - Replace simulateJWSSpiffeID with mock signature provider so tests exercise the full reconciler binding path instead of pre-setting status - Update mockFetcher to return valid AgentCardData (was returning nil) Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
Signed-off-by: Kevin Cogan <kevin.s.cogan@gmail.com>
kevincogan
force-pushed
the
refactor/targetref-migration
branch
from
February 17, 2026 13:29
06d1b86 to
d8805b9
Compare
usize
approved these changes
Feb 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR removes all
selectorbased fallback paths from the AgentCard Identity Binding and Signature Verification features, makingtargetRefthe sole mechanism for workload resolution.This cleans up the dual code paths introduced in #176 for backward compatibility and aligns with the broader
targetRefmigration tracked in #177 .What Changed
Controllers
agentcard_controller.gogetWorkload()now exclusively usestargetReffindMatchingWorkloadBySelector,selectorMatchesAgent,selectorMatchesWorkload, typed ready-check helpers, andErrMultipleAgentsMatchedagentcard_networkpolicy_controller.goresolveWorkload()now requiresspec.targetRefstatus.targetRefand allselectorfallback pathsagentcardsync_controller.goWebhook
agentcard_webhook.gospec.targetRefis now requiredselectoremits a deprecation warning if present, but is ignoredConfiguration
cmd/main.go--enable-legacy-agent-crddefault changed fromtrue→falseTests
Migrated all identity binding and signature verification tests from Agent CRD + selector → Deployment + targetRef
Removed:
findMatchingWorkloadBySelectortest blocklistAgentCardsForAgenthelperDocumentation
a2a-signature-verification.mdtargetRefidentity-binding-quickstart.mdRelated Issues / PRs
targetRefmigration)Testing
Unit tests
End-to-end demos
Verified in a clean kind cluster:
docs/identity-binding-quickstart.mddocs/a2a-signature-verification.mdFixes #177