Skip to content

Repository files navigation

Actime

License: MIT CI

The effect plane for AI coding agents: kernel-enforced policy, system observability, and session backup, attached to the agent you already run, wherever it already runs.

$ actime run -- claude

Your engineers are running Claude Code, Codex, Gemini CLI, and OpenCode on company laptops, CI runners, and cloud sandboxes. Each one can spawn shells, rewrite files, reach the network, and burn a machine's CPU. When something goes wrong, the agent's own transcript is the only account of what happened — written by the thing you are trying to audit.

Actime attaches three planes to the agent's process tree, unmodified:

Plane Component Question it answers
Policy ActPlane (eBPF) What is the agent allowed to do?
Observability AgentSight (eBPF) What did the agent actually do?
Backup Akeep What did the agent decide, and can we replay it?

What you get back is not a log the agent wrote. It is what the kernel saw.

Actime does not manage sandboxes. Bring your own sandbox, or none at all. Actime attaches to the process tree either way.

The sandbox contains. Actime accounts.

That line describes roles, not position. The invariant that is always true is that Actime observes and enforces below the tool layer, at the syscall/effect boundary.


Quick start

# 1. Install (Linux x86_64/aarch64; or build from source, see below)
curl -fsSL https://raw.githubusercontent.com/eunomia-bpf/actime/main/scripts/install.sh | sh

# 2. Check what your machine supports
actime doctor

# 3. Check which policy rules this host can actually enforce
#    (no privileges needed)
actime policy check

# 4. A first run — works unprivileged, with no engines installed
actime run --policy off --no-backup -- /bin/echo hi

# 5. Read the record
actime report

actime policy check compiles the configured policy and prints one line per rule: enforceable on this host, or not, with the missing engine feature named. It loads nothing into the kernel. With the default balanced profile:

ok policy compiled from coding-agent-baseline · 2/2 rules enforceable on this host

RULE                     EFFECT   ENFORCEABLE  REASON
destructive-vcs          kill     yes
mass-deletion            kill     yes

That first run uses no eBPF and no privileges; it still produces a manifest and a report, with the policy and observability planes marked Disabled and the reason recorded. For the full three planes, install the engines Actime drives and run your real agent:

cargo install actplane agentsight akeep

actime run -- claude

There is nothing else to configure. actime run with no actime.yaml uses the balanced profile and turns on every plane your kernel and privileges allow. Whatever is unavailable degrades the run rather than aborting it, with one exception: policy.mode: enforce fails closed. See Degradation.

What you get back

Every run ends with a report on the terminal and on disk. Real output of the quick-start run above, on a machine without the engines installed:

Actime run report
------------------------------------------------------------------------
  Run id:     20260805-124610-f7db
  Agent:      command
  Argv:       /bin/echo hi
  Duration:   1.7s
  Exit code:  0
  Profile:    balanced

Target
------------------------------------------------------------------------
  kind:       command
  spec:       /bin/echo hi
  host_pid:   3577921
  note:       launched as a host child process

Planes
------------------------------------------------------------------------
  policy     Disabled   policy.mode is off
  observability   Degraded   agentsight produced no process/file/network observatio…
  backup    Disabled   backup.enabled is false

Summary
------------------------------------------------------------------------
  violations=0      blocked=0      killed=0
  processes=0       files_written=0     endpoints=0
  llm_calls=0       tokens_in=0        tokens_out=0
  peak_rss=0 B  cpu=0.00s  duration=1.7s

And with all three planes active on a real agent run (illustrative; this one needs the engines and root or CAP_BPF):

Actime run report
------------------------------------------------------------------------
  Run id:     20260804-153012-a3f1
  Agent:      claude
  Argv:       claude -p add retry logic to the uploader and run the tests
  Duration:   4m12s
  Exit code:  0
  Profile:    balanced

Target
------------------------------------------------------------------------
  kind:       command
  spec:       claude -p add retry logic to the uploader and run the tests
  host_pid:   4124801
  note:       launched as a host child process

Planes
------------------------------------------------------------------------
  policy     Active
  observability   Active
  backup    Active

Summary
------------------------------------------------------------------------
  violations=2      blocked=0      killed=2
  processes=214     files_written=18    endpoints=6
  llm_calls=37      tokens_in=411995   tokens_out=9102
  peak_rss=1.9 GiB  cpu=221.00s  duration=4m12s

Policy violations (2)
------------------------------------------------------------------------
  RULE                 EFFECT   TARGET                   REASON
  destructive-vcs      kill     /usr/bin/git             Force-pushing, ha…
  mass-deletion        kill     /usr/bin/rm              Recursive deletio…

Next steps
------------------------------------------------------------------------
  • actime report 20260804-153012-a3f1 --markdown
  • actime report 20260804-153012-a3f1 --json
  • Review blocked/killed violations in ~/.local/share/actime/runs/20260804-153012-a3f1/violations.jsonl

The full record lives in ~/.local/share/actime/runs/<run-id>/: the manifest, the effective config, the exact policy that was loaded, every violation as JSONL, the AgentSight observability database, and a rendered report.md. Override the root with ACTIME_HOME. actime report <id> --markdown adds a timeline section; --json emits the whole record for tooling.

Where Actime sits: three deployment positions

Actime's position relative to a sandbox is a deployment choice, not an architectural constraint. All three are supported:

Position When to choose it Tamper story
A Outside the sandbox — Actime on the host, attached to an existing container's process tree (actime attach --container, --pod) You own the host: workstations, CI runners, self-managed Kubernetes nodes. Needs root or CAP_BPF on the host Strongest: root inside the container cannot disable the recorder or edit the record
B Inside the sandbox — Actime in the same container/VM as the agent (actime run -- claude, inside) You do not own the host: E2B, Daytona, AWS AgentCore, managed Kubernetes, someone else's microVM. Also how a sandbox vendor ships Actime in its image Weaker: root inside the container can interfere. The container needs CAP_BPF (often plus CAP_PERFMON/CAP_SYS_ADMIN) granted to it
C No sandbox at all — a plain process on a machine The common workstation case Same as host-side attach to a plain process tree

Position B is the only option on managed sandbox platforms, and its weaker tamper story is real: an agent with root in its own container can interfere with a recorder running in the same container. We say so plainly wherever it matters, and actime doctor detects the in-container case and tells you. Never read a host-side guarantee into a position-B deployment.

The setup for each position — including the docker run --cap-add incantation for B and host-side attach for A — is in docs/deployment.md.

Why this layer

Most agent guardrails sit at the tool layer: the framework asks permission before it calls a tool. That works right up to the moment the agent writes a shell script, and a coding agent's whole job is writing shell scripts.

Actime enforces below the tool layer, at the syscall boundary, where the effect actually happens. This is independent of where Actime is deployed:

The agent does Tool-layer guardrail Actime
calls a blocked tool blocked blocked
bash -c the same thing passes blocked
a Python subprocess does it passes blocked
a subagent it spawned does it usually passes blocked, lineage is inherited
reads a secret, then posts it from another process invisible expressible — see below; not enforceable with released ActPlane 0.1.8

The first four rows are what Actime enforces today: exec-level rules (git --force, rm -rf, git push) that hold below the tool layer no matter how the agent reached the syscall.

The last row is the design's core idea, and it is not a shipping capability yet. The policy language does not just match calls, it can express where data came from. A value read out of .env, copied into a temp file, piped through jq, and sent by a subprocess is still labeled when it reaches the socket:

rule no-secret-egress:
  kill connect endpoint "*" if AGENT and SECRET
  because "This process holds data derived from a secret file and tried to open a network connection..."

No syscall allowlist can express that, because the offending syscall is an ordinary connect. What makes it a violation is its history. That rule ships in the information-flow pack — but enforcing it needs engine features (file-source label propagation, path contains/suffix matchers) that released ActPlane 0.1.8 does not provide on the attach path Actime uses, so today the rule compiles, is reported as not enforceable by actime policy check, and --policy enforce refuses to start a run that requests it. When the engine enables those rule classes, the same pack becomes enforceable with no doc change. docs/policies.md has the full story.

Architecture

                 your agent, unmodified
                 claude · codex · gemini · opencode · any command
                              │
                     existing process tree
                     (a container you made, a pod, or a plain process)
                              │
        ┌─────────────────────▼─────────────────────┐
        │  policy plane      ActPlane   (eBPF)      │   ← constrains
        │  observability plane    AgentSight (eBPF)      │   ← accounts
        │  backup plane     Akeep                  │   ← preserves
        └─────────────────────┬─────────────────────┘
                              │
                       run record + report

Actime never creates, starts, stops, or removes a container or pod. actime attach --container / --pod only resolve targets that already exist — that is how Actime composes with other people's sandboxes.

Actime does not reimplement the planes. It composes three existing projects into one runtime, one config file, and one report:

Plane Project What it contributes
Policy ActPlane kernel enforcement of policy rules: exec-level rules today, labeled information flow as the engine enables it
Observability AgentSight process, file, network, TLS, and resource observations
Backup Akeep versioned, restorable agent session history

The eBPF instrumentation underneath comes from bpftime. Each project remains useful on its own; Actime is how you install, run, and operate them together.

Actime needs actplane ≥ 0.1.8, agentsight ≥ 0.2.60, and akeep ≥ 0.2.0. actime doctor checks the versions it finds and tells you what to upgrade.

Policy

Policies are ActPlane rules over real OS effects. Actime ships three packs and you can add your own:

# actime.yaml
policy:
  mode: enforce                 # off | observe | enforce
  packs:
    - coding-agent-baseline     # destructive VCS, mass deletion — enforceable today
    - no-vcs-write              # the agent edits, the human publishes — enforceable today
    - information-flow          # file fences, secret-egress labels — needs engine
                                # features released ActPlane 0.1.8 does not ship
  files:
    - ./team-policy.dsl

Which rules your host can actually enforce is a host property, not a pack property. actime policy check is how you find out — it compiles the configured policy, loads nothing, needs no privileges, and prints one line per rule:

$ actime policy check        # packs: [information-flow]
ok policy compiled from information-flow · 0/4 rules enforceable on this host

RULE                     EFFECT   ENFORCEABLE  REASON
credential-access        notify   no           engine missing features required on attach/delta path: path contains matches, path suffix matches
run-record-integrity       block    no           engine missing features required on attach/delta path: path contains matches, write sink rules
no-secret-egress         kill     no           engine missing features required on attach/delta path: path contains matches, path suffix matches
system-fence             block    no           engine missing features required on attach/delta path: write sink rules

With released ActPlane 0.1.8, exec-based rules (coding-agent-baseline, no-vcs-write) install and fire; the file-sink and label-propagation rules in information-flow — including no-secret-egress — do not. Two consequences:

  • --policy enforce fails closed: if any requested rule is not enforceable, the run aborts before the agent starts (exit 1) rather than silently enforcing a subset.
  • --policy observe proceeds, but the unenforceable rules are recorded in the manifest and printed in the report, so the record never claims the run watched for something it did not.
actime policy list              # packs and what each one forbids
actime policy show no-vcs-write
actime policy check             # per-rule enforceability on this host
actime policy explain           # how each clause lowers to kernel matchers

check and explain call the installed actplane binary; they compile the policy but never load it into the kernel, so they need no privileges.

Start with --policy observe. Nothing is blocked, everything is recorded, and after a week you will know which rules you actually want. Then move them to enforce one at a time.

When a rule fires, the agent is told why, in words, through ActPlane's feedback interface, so it corrects course instead of retrying the same blocked action.

See docs/policies.md.

Degradation

Actime is built to be useful on a laptop with no root and no container runtime, and stricter as the environment allows. Nothing below aborts an observe run:

Missing What happens
root / CAP_BPF policy and observability planes disabled; backup still runs; doctor explains
running inside a container without CAP_BPF same; doctor warns that this is deployment B without host-side tamper-resistance
actplane policy plane disabled in observe mode; a hard failure in enforce (fail closed)
agentsight observability plane disabled; process-level fallback still records argv, exit, duration
akeep backup plane disabled
kernel < 5.10 policy plane disabled, with your kernel version in the reason
a rule needs engine features the host lacks enforce: the run aborts before the agent starts; observe: the run proceeds with the rule recorded as unenforceable in the manifest and report

Every run produces a manifest and a report, even when only the fallback ran. actime doctor tells you exactly which planes your machine supports and how to turn on the rest.

Requirements

  • Linux. The policy and observability planes need kernel 5.10+ with BTF (/sys/kernel/btf/vmlinux); 6.1+ is recommended for the full runtime. The backup plane has no kernel requirement.
  • Root, or CAP_BPF/CAP_PERFMON on the engine binaries, for the policy and observability planes only. Everything else runs unprivileged.
  • A container runtime (Docker/Podman) or kubectl only if you want actime attach --container / --pod to resolve those targets. Actime itself never starts a container.

macOS is not supported: the prebuilt binaries are Linux-only, and the eBPF planes need a Linux host kernel.

Documentation

Who this is for

Platform and security teams that already have coding agents inside the building, on machines the company owns — or in sandboxes someone else runs — and need to answer: which agents ran, what did they touch, what did they send where, what did they cost, and what stopped them. Actime is not a hosted sandbox service and does not want your code. It is local-first and sends nothing anywhere.

Related work

Actime deliberately does not compete with hosted agent-execution platforms (AWS AgentCore, E2B, Daytona): bring your own environment and Actime layers onto it — from the host where you own one, or inside the sandbox where you do not. It also does not sit at the identity or tool-authorization layer. It owns the layer between: what the agent's actions actually do to a machine, and the record of it.

Contributing

Issues and pull requests are welcome. See CONTRIBUTING.md and SECURITY.md.

License

MIT. See LICENSE.

About

Unified runtime for AI coding agents: sandbox isolation, kernel-enforced policy, system evidence, and session history in one command

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages