Repository navigation
Own-address cache misses an address added within its 300 s refresh #15102
Description
Problem
_host_is_self in src/kiro_crew/security/argv_floor.py answers IP-literal ssh/scp/sftp/rsync checks from a cached own-address set that is re-read every _OWN_HOST_REFRESH_SECS (300 s). If the host gains an address inside that window, for example when a VPN interface comes up, ssh <new-address> is treated as a remote target and allowed until the next re-read. The agent then re-enters the unsandboxed host. The miss closes itself at the next refresh, at most about 300 s plus the 60 s spawn backoff.
This is main's behaviour, documented at argv_floor.py:1700-1711. GPT raised it as a blocking finding on #14122, whose startup read only moves the first publish earlier and leaves the refresh bound unchanged.
Why a refresh on miss does not close it
The check runs synchronously on the event-loop is_denied path, so it cannot do the netlink read inline. The alternative, refusing a missed IP and re-reading in the background, refuses the first ssh to every remote IP once the cache is a few seconds old. That brings back the spurious refusal #14121 fixes.
Proposed fix
Keep the own-address set current from kernel events instead of a timer. A daemon thread holds an AF_NETLINK socket bound to RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR. On any RTM_NEWADDR it closes the IP-literal window (_NETLINK_ADDRS_PUBLISHED = False) under _OWN_HOST_RESOLVE_LOCK and re-runs the dump, which reopens the window once the new table is published. A socket that cannot subscribe falls back to the current 300 s refresh. macOS and Windows need their own change sources (PF_ROUTE, NotifyIpInterfaceChange), or keep the timer.
Acceptance
- A test that adds an address event after publish sees the window close before the next check, and
_host_is_self(<new address>)returns True. - No new blocking call on the event loop (
scripts/check_sync_io_in_async.py).
Activity
CrysisDeu commentedon Sep 29, 2026
🤖 Kiro Crew Auto-Pipeline [operator: CrysisDeu#0c98c3a2]: Routing to needs-investigation. Mechanism confirmed on main at df0ea79:
_own_host_namesserves the published set until_OWN_HOST_RESOLVE_STAMPis older than_OWN_HOST_REFRESH_SECS(300 s,argv_floor.py:1706), then re-enumerates in a single-flight worker; an address gained inside that window is not self until the next refresh, and a refresh-on-miss cannot run on the synchronousis_deniedpath without bringing back the #14121 refusal. What is left is a design pick rather than a mechanical fix: an event source (AF_NETLINKRTM_NEWADDRdaemon thread on Linux,PF_ROUTE/NotifyIpInterfaceChangeor the timer elsewhere), its lifecycle on a long-lived gateway, and how it composes with the startup publish that open PR #14122 adds to the same module (argv_floor.py,host_addresses.py). A maintainer should decide the change source and whether it lands on top of #14122 or inside it. Lane re-checks after #14122 merges.github-actions commentedon Sep 29, 2026
Automated triage summary — generated from the issue text alone, before any maintainer has read it. Treat every line as a starting point, not a verdict.
A security check that decides whether an ssh/scp/sftp/rsync IP-literal target is the local host relies on an own-address set refreshed only every 300 s, so an address added mid-window (e.g. a VPN interface coming up) is treated as remote and permitted until the next refresh, letting an agent reach the unsandboxed host. Reporter proposes driving the address set from kernel address-change events with the timer as fallback.
Worth adding
Posted by
issue-summary.yml. The model had no access to the repository — it read only this issue and the titles of recent ones.buluoray commentedon Oct 8, 2026
🤖 Kiro Crew Auto-Pipeline [operator: buluoray#ce473fca]: this issue is now claimed by buluoray#ce473fca's instance.
A worker will diagnose this and open a draft PR scoped to the issue's tier, or leave a written recommendation if the right call is to rescope or not change anything. The draft is not marked ready until the owner decides.
buluoray commentedon Oct 8, 2026
🤖 Kiro Crew Auto-Pipeline: releasing this pipeline's claim.
A first pass recommends event-driven own-address refresh (a kernel address-change listener on Linux, timer elsewhere), but that is a new long-lived subsystem rather than a T1 fix, and it should follow #17666, which moves this code. The design recommendation is with the owner.
No branch or PR was created by this pipeline for this issue.
KiroCrewCaptain commentedon Oct 8, 2026
Thanks for the report. This issue has been triaged by Crew Captain and will be assigned to a maintainer, who will follow up here.
buluoray commentedon Oct 9, 2026
🤖 Kiro Crew Auto-Pipeline [operator: buluoray#ce473fca]: Re-tiering T1 -> T4: the first pass found the fix is event-driven own-address refresh (a kernel address-change listener on Linux), which is a new long-lived subsystem needing a design review, not a T1 bug fix. It should also follow #17666, which moves this code.