Skip to content

atenet: classify a 403 route outcome as denied, not resume_error - #2534

Merged
Tim Hockin (thockin) merged 1 commit into
agent-substrate:mainfrom
giantswarm:upstream/egress-denied-outcome
Oct 23, 2026
Merged

Tim Hockin (thockin) merged 1 commit into
agent-substrate:mainfrom
giantswarm:upstream/egress-denied-outcome

Conversation

@teemow

Copy link
Copy Markdown
Contributor

Problem

classifyOutcome in cmd/atenet/internal/router/extproc/metrics.go maps a ReqError by its HTTP status: 404 → not_found, 503 → unavailable, 504 → timeout, 429 → rate_limited. A 403 has no case and falls through to resume_error, which the registry describes as "the resume failed for a different reason. The router has a defect." Every egress policy refusal (destination outside the policy, no policy, actor not running, invalid actor certificate) and every ingress PermissionDenied therefore records ate.router.outcome=resume_error on atenet.router.route.duration, so an alert on router defects fires on ordinary policy decisions and a real resume failure hides among them.

Change

  • New ate.router.outcome value denied (ateattr.RouterOutcomeDenied): a 403 ReqError and a PermissionDenied status classify as denied; everything else keeps its outcome, and resume_error is left for a resume that failed for any other reason.
  • Registry (docs/metrics/registry/metrics.yaml), the ateattr comment and the outcome list in docs/observability.md list denied. The unavailable outcome no longer names a denied egress request among its examples, since a denial answers 403.

Testing

  • metrics_test.go: PermissionDenied, a bare 403 and a 403 wrapping an uncoded cause classify as denied; an uncoded error, an Internal status and a 500 ReqError still classify as resume_error.
  • go test ./cmd/atenet/internal/router/extproc/ ./internal/ateattr/, hack/verify/golangci-lint.sh, hack/verify/metrics.sh.

This PR was written by an AI agent on behalf of the author.

classifyOutcome maps a ReqError by its HTTP status, and a 403 had no
case, so it fell through to resume_error, which the registry describes
as a router defect. Every egress policy refusal (a destination outside
the actor's policy, no policy, an actor that is not running, an invalid
actor certificate) and every ingress PermissionDenied therefore counted
as resume_error on atenet.router.route.duration: an alert on router
defects fired on ordinary policy decisions, and a real resume failure
hid among them.

A 403 ReqError and a PermissionDenied status now record the new outcome
denied. resume_error is left for a resume that failed for any other
reason. The registry, the ateattr comment and docs/observability.md
list the new value; the unavailable outcome no longer names a denied
egress request among its examples, since a denial answers 403.
@bowei Bowei Du (bowei) added area/network area/observability kind/bug Something isn't working / bugfixes labels Oct 14, 2026
auto-merge was automatically disabled October 21, 2026 23:19

Pull request was closed

@thockin
Tim Hockin (thockin) added this pull request to the merge queue Oct 23, 2026
Merged via the queue into agent-substrate:main with commit 4ebd668 Oct 23, 2026
24 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/network area/observability kind/bug Something isn't working / bugfixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants