Skip to content

Hostname auto-allows have no deny-veto: an infra allow overrides an operator's exact-name deny #121

Description

@matthewdevenny

Symptom

An operator rule that denies a hostname is silently overridden when an infrastructure auto-allow names the same hostname. Policy {"type":"hostname","value":"blob.core.windows.net","action":"deny"} on an Azure runner loses to autoAllowAzure's allow:

post-load auto-allow  -> HasAllow=true HasDeny=false allowRule="blob.core.windows.net" denyRule=""

The CIDR path does not behave this way. ensureAllowed calls cidrDenyCoversLocked and skips loudly:

Skipping auto-allow: an explicit deny rule covers this network cidr=... autoAddedType=...

ensureHostnameAllowedLocked has no equivalent. It dedups only against an existing allow (trackedHostnames[hostname] == ActionAllow), so a denied name falls through, the allow is appended after the policy's deny, and matchHostnameRuleLocked hands the verdict to the last exact match — the auto-allow.

Not a regression

Pre-#119 the auto-allow pass ran after the config load and appended the same rule to the same slice; the replay layer reproduces that ordering exactly. Both orderings produce the identical verdict, pinned by TestAutoAllowReplay_HostnamePrecedenceUnchangedByOrdering (#120). This issue is the underlying asymmetry, not the reorder.

Scope of the override

Only an exact-name collision is questionable. A parent deny losing to a more specific auto-allow (policy denies core.windows.net, auto-allow names blob.core.windows.net) is the documented exact-beats-parent precedence and is arguably correct — the operator denied a domain, the daemon allowed one host under it that CI cannot run without. The exact-name case has no such defence: the operator named precisely the host the auto-allow names, and lost.

Proposal

Give the hostname path the CIDR path's veto: in ensureHostnameAllowedLocked, skip when the loaded ruleset already denies that exact name (and, for a port-limited auto-allow, when the deny covers those ports), logging the skip the way ensureAllowed does. trackedHostnames already carries the action, so the check is a branch on the lookup that is there.

Worth deciding at the same time:

  • Whether a deny pattern that matches the name (*.core.windows.net) should also veto. Patterns outrank parent rules but not exact matches today, so a pattern-vs-auto-allow collision has the same shape.
  • What the run does afterwards. Denying blob.core.windows.net on an Azure runner breaks Actions telemetry uploads; the operator asked for that, but the failure should be legible — the skip log line is what makes it so.

Out of scope

  • The parent/pattern precedence rules themselves (matchHostnameRuleLocked), which are load-bearing elsewhere.
  • Auto-allow types the run cannot function without (loopback, the SaaS API hostname the policy fetch itself needs) — a veto there would let a policy lock the daemon out of its own control plane. If the veto lands, those may need to be exempt, which is its own decision.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions