Disclosure: this issue was written by an AI agent (Claude) while working on a cluster
stood up by scripts/setup-cluster/setup-cluster.sh, and reviewed by a human before filing.
Summary
Both setup-cluster.sh and the CI workflow write an ate-api-authentication ConfigMap with
issuer: https://kubernetes.default.svc, but a kind cluster advertises
https://kubernetes.default.svc.cluster.local. Because the issuer does not match, bearer
auth to ate-api fails and kubectl-ate cannot be used to inspect Actors or ActorTemplates.
Evidence
On a cluster created by setup-cluster.sh (kagent b8d53d39, substrate 0.0.25, Kubernetes 1.35):
$ kubectl get --raw /.well-known/openid-configuration | jq -r .issuer
https://kubernetes.default.svc.cluster.local
$ kubectl get configmap ate-api-authentication -n ate-system \
-o jsonpath='{.data.authentication\.yaml}' | grep issuer
issuer: https://kubernetes.default.svc
Result:
$ kubectl-ate get actor-template ...
rpc error: code = Unauthenticated desc = invalid bearer token
Where it is written
scripts/setup-cluster/setup-cluster.sh:62
.github/workflows/ci.yaml:104
Both use the same inline literal:
actorIdentityJWTProvider: kubernetes
jwtProviders:
- name: kubernetes
issuer: https://kubernetes.default.svc
audiences: [api.ate-system.svc]
...
Impact
kagent itself is unaffected — the controller reaches ate-api over mTLS/SPIFFE, and
AgentInstances work normally. What breaks is the one clean way to inspect what a compiled
revision actually delivers to an Actor, which makes debugging substrate-backed behaviour
considerably harder than it needs to be.
Suggested fix
Read the issuer from the cluster rather than hardcoding it, for example:
issuer="$(kubectl get --raw /.well-known/openid-configuration | jq -r .issuer)"
If the existing entry must stay as-is because actor identity depends on it, adding a second
jwtProviders entry carrying the .cluster.local issuer also resolves it without changing
the first.
Summary
Both
setup-cluster.shand the CI workflow write anate-api-authenticationConfigMap withissuer: https://kubernetes.default.svc, but a kind cluster advertiseshttps://kubernetes.default.svc.cluster.local. Because the issuer does not match, bearerauth to ate-api fails and
kubectl-atecannot be used to inspect Actors or ActorTemplates.Evidence
On a cluster created by
setup-cluster.sh(kagentb8d53d39, substrate 0.0.25, Kubernetes 1.35):Result:
Where it is written
scripts/setup-cluster/setup-cluster.sh:62.github/workflows/ci.yaml:104Both use the same inline literal:
Impact
kagent itself is unaffected — the controller reaches ate-api over mTLS/SPIFFE, and
AgentInstances work normally. What breaks is the one clean way to inspect what a compiled
revision actually delivers to an Actor, which makes debugging substrate-backed behaviour
considerably harder than it needs to be.
Suggested fix
Read the issuer from the cluster rather than hardcoding it, for example:
issuer="$(kubectl get --raw /.well-known/openid-configuration | jq -r .issuer)"If the existing entry must stay as-is because actor identity depends on it, adding a second
jwtProvidersentry carrying the.cluster.localissuer also resolves it without changingthe first.