Direct answer: namespace membership, not parentage, defines the scope
In the v1.0.35 process probe, --pidns-of PID opens /proc/PID/ns/pid and pins the target namespace. The in-kernel filter accepts a task if the target PID namespace appears anywhere in that task's namespace ancestry. That includes tasks in the selected namespace and nested namespaces, including independently parented processes in the same namespace. It excludes tasks outside that ancestry. Separate PID, command, and cgroup filters can narrow the result further.
This is an inspection of AgentSight release v1.0.35, product commit c1574366122a90c451bca6a84713e28813ab95e2, not a measured production coverage claim. The switch belongs to the Linux process probe, demonstrated through agentsight debug process; do not assume it is a universal agentsight record flag, a container security policy, or an automatically configured Kubernetes sidecar.
Why the two usual selectors fail in a sidecar
A parent-PID/process-tree selector starts from a chosen process. But docker exec-style tasks may be independently parented instead of descendants of the container init. A container cgroup selector is useful when the observer can resolve that cgroup. A sidecar with private mount and cgroup namespaces may not see a sibling workload's cgroup path under its own /sys/fs/cgroup. Neither failure says that eBPF itself cannot see the target task; it says that the chosen selection key is unsuitable.
PID namespace membership answers a different question: which running tasks are visible from the target's PID namespace? The sidecar must still see the target PID under its own /proc, have the needed tracing privileges, and run on a Linux host with compatible probe support.
Scope matrix: what would a selected namespace include?
| Task topology | Expected process-probe result | Reason |
|---|---|---|
| Target process in the selected PID namespace | Included, subject to additional process/cgroup filters. | Its namespace is the selected namespace. |
| Child inside a nested PID namespace | Included, subject to additional filters. | The target namespace occurs in the child task’s namespace ancestry, even if it is not the innermost namespace. |
| Independently launched process in the same namespace (for example docker exec) | Included with namespace scoping alone. | The BPF check asks where the task is visible, not whether its parent PID descends from the original container init. |
| Process outside the selected namespace and its descendants | Excluded. | The task’s namespace chain never contains the pinned namespace identity. |
| Another container sharing the same PID namespace | Not isolated from the target by this filter. | A PID namespace is not a container identity or authorization boundary. |
| Process in the namespace but rejected by an additional PID or cgroup filter | Excluded. | Combined filters intersect; namespace membership does not override narrower selectors. |
The table describes the filter predicate, not a guarantee that every syscall, open, or network event is emitted. Event categories depend on the probe's enabled flags, kernel hooks, buffering, deduplication, and loss. In particular, the filter cannot distinguish two containers sharing a PID namespace. A nested sandbox is included because the selected namespace is an ancestor, not because its inner PID values match the outer namespace.
The actual BPF test walks namespace ancestry
The source function task_visible_in_target_pidns() obtains the current task's thread_pid, walks its kernel struct pid namespace-number chain up to the bounded maximum of 32 levels, and compares each namespace's inode with the pinned target. That matters for tools such as bubblewrap or unshare --pid: their innermost PID namespace differs from the selected outer namespace, but they remain visible to that outer namespace.
The code intentionally does not depend on bpf_get_ns_current_pid_tgid() as a simple equality test: that helper does not express the ancestor-membership check needed here. The loader opens the namespace descriptor before attaching, obtains its device/inode, and keeps the descriptor open until cleanup to protect the scope from inode reuse after the original PID exits. The BPF path applies this predicate before other configured cgroup selection.
Because the namespace itself is pinned, replacing the target container does not silently retarget the probe. The operator must resolve the replacement's PID and restart the probe. That is an intentionally conservative failure mode, not automatic container discovery.
Reproduce a bounded process-scope check
First choose a PID visible from the sidecar's /proc that belongs to the target namespace. Verify that choice independently by inspecting the namespace symlink on the host. Next run the documented standalone process probe or its wrapped debug command, enable only the event categories needed for the question, and observe a bounded interval:
readlink /proc/<target-host-pid>/ns/pid
# From the v1.0.35 build on a privileged Linux host:
sudo agentsight debug process -- -m 0 --pidns-of <target-host-pid> --trace-net --heartbeat 2During that interval, examine a known in-namespace command, an independently launched process in the same namespace when one is available, and a control process outside the namespace. Add a nested PID namespace case when your environment supports it. Treat an absent file or network row as inconclusive until you have checked its hook, flags, aggregation, and loss reports. This is a reproduction method, not an assertion that the command was run in this editorial cycle.
The v1.0.35 implementation PR documents a real Linux namespace reproduction with private cgroup/mount/PID namespaces: an independent nsenterprocess, file open, listener, and accepted peer were captured, while an outside workload was excluded. The PR explicitly reports no Docker daemonin that test environment. It therefore validates namespace behavior, not every Docker or Kubernetes deployment topology.
Probe liveness answers a different question from event coverage
Add --heartbeat 2 to receive a start record and periodic PROBE_LIVENESS events. The process runner normalizes them onto the ordinary process event stream using pid: 0 andcomm: "process". The heartbeat timestamp is monotonic, consistent with BPF event timing; wall_time_ns is Unix epoch nanoseconds for external freshness checking. The start record includes the enabled trace flags.
A recent heartbeat establishes that the probe's event loop is alive; it does not establish correct target identity, comprehensive hook coverage, or zero data loss. A missing heartbeat after a crash is a monitoring signal, not evidence that the target agent stopped. Preserve the difference between observer health, namespace scope, and observed effects.
Decide which observation plane you actually need
This probe concerns process, file, network, and selected extension events from Linux execution. It does not reconstruct prompts, model usage, or provider sessions merely because the process was in scope. For TLS plaintext you still need a compatible runtime/binary attachment and HTTP parser; see TLS capture boundaries andHTTP exchange correlation.
The separate Docker native-session bridge accesses provider-owned session data through a Node inside the container; it is not the same mechanism as the privileged Linux PID namespace probe. A hybrid investigation may need both, and should preserve their provenance independently.
In an incident, record the AgentSight version, selected host PID, namespace symlink identity, host kernel, sidecar /procvisibility, trace flags, any other filters, and time interval. Also check event-loss and fallback notices. Without these details, a negative trace is too ambiguous to support a security conclusion.
Primary sources and limitations
All AgentSight implementation claims are pinned to the public v1.0.35 commit c1574366122a90c451bca6a84713e28813ab95e2. The scope matrix is deduced from the documented BPF predicate, not measured coverage percentages. No new benchmark, customer case, or independent Kubernetes sidecar test is claimed here. Privileged host tracing entails its own deployment and data-handling risks; event streams can contain executable names, paths, peers, and other sensitive evidence. Keep captures local or redact them before sharing.
- v1.0.35 process probe reference and examples
- BPF namespace ancestry check and filter composition
- Probe argument parsing, namespace pinning, and heartbeat
- Namespace runtime and liveness regression tests
- Collector liveness normalization and parser tests
- Implementation PR #237: reproduction scope and limitations
- Nested namespace inclusion fix, PR #244
- Docker child-thread resolution fix, PR #246
- AgentSight v1.0.35 release
For the higher-level question of when to select system capture instead of native agent records, read eBPF monitoring evidence boundaries. Installation, privilege setup, and maintained CLI reference remain on the canonical product documentation.