Skip to content

sureshrupasinghe89/agent-manager-security-probe

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Security Probe Agent — Spec

Benign, read-and-report enumeration agent onboarded via the Source Code path to answer the "does the sandbox hold?" questions from inside a running agent pod. Implements §4 of the security test plan.

Target for this engagement: console.agent-manager.cloud.wso2.com (ALPHA). Report channel: controlled webhook (PROBE_WEBHOOK_URL). Runtime: portable bash.


1. Safety boundaries (non-negotiable)

The probe is enumeration, not a weapon. It:

  • Only reads its own runtime context. No writes, no deletes, no process injection, no lateral movement.
  • Masks all secret values. It reports names/paths/lengths and a short non-reversible fingerprint — never raw secrets. For the SA token it decodes only the non-secret JWT claims (namespace, audience, expiry), never the signature.
  • Does not touch other tenants. Cross-tenant reach is inferred from the self-permission review and TCP connect checks only. It never enumerates or reads another tenant's objects.
  • Fail-flag, not fail-forward. If self-review or reachability indicates cross-tenant access is possible, that is reported as a finding and escalation stops until the operator makes the call. (Per your instruction on this run.)

Everything above keeps the probe inside "authorized environment enumeration." Actual escape / lateral movement is a separate, explicitly-authorized step.


2. What it collects → why it matters

Field(s) Plan / ATT&CK link Answers
user, uid, gid, is_root, cap_eff, no_new_privs §C securityContext; T1611 Root? Dangerous caps? no-new-privs on?
base_image_osrelease, kernel §4 CVE mapping Known-CVE surface for escape
rootfs_root §C read-only FS Is the root filesystem writable?
mount_points, docker_sock_present, host_proc_mounted §C host mounts; T1611 Escape primitives present?
env_var_names, env_sensitive (masked) T1552.001 Secrets injected via env?
sa_token_present, sa_namespace, sa_token_claims, sa_token_masked T1552.001 / T1528 SA token mounted? What identity/scope?
self_rules_review* §C RBAC; T1069 What can this pod's identity actually do?
reach_metadata_80 §C metadata; T1552.005 Cloud metadata endpoint reachable?
reach_apiserver_443, reach_dns_53 §C kube-apiserver; T1046 Control-plane reachable from pod?
reach_egress_webhook §E exfil path Does egress to internet work?

All reachability checks are TCP connect only — no data is pulled from the metadata endpoint or the API server beyond the self-review introspection call.


3. Configuration (env vars)

Var Default Purpose
PROBE_WEBHOOK_URL (empty) Controlled OOB endpoint to POST JSON to. Empty = stdout-only.
PROBE_ID probe-$$ Label this run. Use probe-A / probe-B for the two-tenant test.
PROBE_CONNECT_TIMEOUT 3 Seconds per network check.
PROBE_METADATA_IP 169.254.169.254 Metadata IP (same for AWS/GCP/Azure link-local).
PROBE_LINGER 2 Seconds to stay alive before exit 0.

Never hardcode the webhook URL in the repo — pass it as a deploy-time parameter/env so it isn't committed.


4. Onboarding via the Source Code path (CONFIRMED in Phase A)

There is no repo descriptor file. Onboarding is a console form under Add Agent → Platform-Hosted Agent, with these fields:

Field Value for the probe
GitHub Repository a repo you control containing the probe
Branch main
App Path subdir holding the probe
Language Python (buildpack) or Dockerfile path
Start Command python main.py (buildpack)
Port 8000
Interface Chat Agent
Env vars PROBE_WEBHOOK_URL=..., HOME=/tmp, PROBE_ID=probe-A

Hard build constraint (verified): the build pipeline runs podman build, then rejects any image whose USER is root ("Agent images are required to run as non-root"). So a Dockerfile MUST declare a non-root user or the build fails.

Runtime constraints the probe must live within (verified from the SandboxTemplate):

  • Runs as UID 65534 (nobody), readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, all capabilities dropped, seccomp RuntimeDefault. Only /tmp, /data, /home/nobody/.cache are writable.
  • Egress NetworkPolicy allows: DNS, the openchoreo data-plane / gateway namespaces, and public 443/80 only — with RFC1918 and 169.254.0.0/16 explicitly blocked. So: the webhook must be a public HTTPS endpoint, and the metadata-IP / apiserver connect checks are expected to fail if the policy is enforced (see §2a).

Option A — Dockerfile path (recommended for a bash probe):

FROM alpine:3.20
RUN apk add --no-cache bash curl
COPY probe.sh /probe.sh
RUN chmod +x /probe.sh
USER 65534
ENTRYPOINT ["/probe.sh"]

(The USER 65534 line is mandatory — without a non-root USER the build is rejected.)

Option B — Python buildpack path: commit a tiny main.py that subprocess-execs probe.sh, set Language=Python, Start Command python main.py. Buildpack images may not ship bash — prefer Option A for the shell probe.

2a. The probe doubles as a NetworkPolicy-enforcement test

Because the SandboxTemplate egress policy should block the metadata IP, RFC1918, and the apiserver: if the probe reports reach_metadata_80: open, reach_apiserver_443: open, or reach_dns_53 to an unexpected target, the egress NetworkPolicy is not being enforced in this environment (CNI gap or policy not applied) — a finding in itself. reach_egress_webhook: open to a public HTTPS host is expected and confirms the probe path works.


5. Set up the webhook receiver

Any endpoint you control that logs POST bodies. Options:

  • A hosted request bin you own (paste the URL into PROBE_WEBHOOK_URL).
  • A one-liner you run locally + a tunnel:
# minimal local receiver (prints each JSON report)
python3 -c 'from http.server import *; import sys
class H(BaseHTTPRequestHandler):
 def do_POST(s):
  n=int(s.headers.get("content-length",0)); print(s.rfile.read(n).decode()); s.send_response(200); s.end_headers()
HTTPServer(("0.0.0.0",8000),H).serve_forever()'

Confirm reachability from the pod separately — if egress is blocked, the reach_egress_webhook: closed field and the failed POST are themselves findings (and you fall back to reading the report from platform/OTel logs, since the probe also prints to stdout).


6. Two-tenant cross-tenant test

Deploy the same probe in tenant A (PROBE_ID=probe-A) and tenant B (PROBE_ID=probe-B). Compare sa_namespace, self_rules_review, and reachability. If B's identity can see/reach A's namespace or objects — stop and flag it to me before any active cross-tenant request.


7. Cleanup (Phase F)

  • Delete/undeploy both probe agents from the console.
  • Revoke any tokens issued for the probe deployments.
  • Rotate the webhook URL.
  • Record what was deployed, when, and its removal in the engagement log.

8. Files

  • probe.sh — the probe (syntax-checked, JSON-validated locally).
  • README.md — this spec.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages