Skip to content

Security, privacy, and redaction

CLI v3.0.2View Markdown

Public guide snapshot. View source. For exact flags in your installation, use olef commands <path> --json.

Olef reads real screens, logs, files, and network traffic from a real device. Everything below exists to keep that evidence from leaking secrets or personal data by accident — and to be explicit where redaction cannot help.

Pass global --redact before or after any subcommand to filter JSON and text at the shared output boundary:

Terminal window
olef --redact ui dump
olef log --last 2m --redact
olef --redact collect --app com.example.app --redact-screenshots
olef net start --redact

Built-ins cover password/secret/token/cookie fields, JWTs, bearer values, emails, IPv4/IPv6 addresses, usernames/phone values, and common session, device, transaction, and serial identifiers. JSON embedded in log or GraphQL body strings is parsed and retains its structure. Each emitted record carries the policy version and replacement count. Config can enable the policy for all commands and add key names or Rust-regex patterns; user and project additions are merged, with the nearest enabled value winning.

UI dumps also recognize values following English Birthdate/Date of Birth/DOB and Device ID/Android ID labels. Recognized date, Android ID and UUID values are removed from duplicate layout and summary text, and from explicitly requested pixel redaction. This does not cover arbitrary labels, every date locale, or text that Android does not expose; add project patterns for those.

net start --redact applies the same policy to completed capture copies before they reach the session log, including URL path/query values, hosts, connection errors, WebSocket metadata, and TLS failures. A live daemon reports its capture-policy fingerprint; requesting --redact refuses to reuse an unredacted or differently configured daemon and asks for an explicit stop/start. Request/response bytes forwarded to the app or upstream are never changed. The session log is written 0600 either way.

ui screenshot reports raw pixels as potentially sensitive. Explicit --redact-pixels (PNG only) blacks out matching accessibility bounds, but still reports that Android may not expose every rendered glyph. collect marks screenshots potentially sensitive unless --redact-screenshots explicitly blacks out matching bounds. The device viewer’s annotation overviews and crops are full-screen pixels too: they are captured with --redact-pixels whenever the redaction policy is on (OLEF_REDACT or redaction.enabled), and report pixels_redacted per screen.

Video is a stricter boundary: global --redact does not alter MP4 pixels. Every video bundle is marked as containing sensitive, unencrypted data; review its clips before sharing it. For video bundles, --redact filters marker labels; device/session identity and recovery paths remain in the protected manifest, so the JSON timeline is still marked potentially sensitive. Screen recording is video-only — it does not capture device, app, or microphone audio.

ui pin enters a numeric PIN without echoing the digits back in action JSON, and deliberately refuses --observe/--expect-* so a returned screen cannot reveal an unmasked keypad. The PIN is still present in the local process invocation, so use the host’s normal shell-history and process-visibility protections. See agent-loop.md.

App state snapshots (app state snapshot) are written 0700/0600, record SHA-256 hashes and a signing-identity digest, and are deliberately marked contains_sensitive_data:true and unencrypted. cleanup overwrites before deletion but cannot guarantee physical erasure on SSD/COW/journaled storage. See device-state.md.

Repository config cannot supply executable device-shell fragments: app packages are validated at deserialization, permission/app-op tokens at their command boundary, and accepted values are quoted before entering an Android shell command. Values containing ;, newlines, $(), quotes, or whitespace fail with a typed invalid_* error. See configuration.md.

  • On first connect, the CLI auto-installs a version-matched APK pair downloaded from the matching GitHub Release, SHA-256 verified, and cached under ~/.olef/apks/<version>/. When working inside the Olef repository it prefers local Gradle build outputs.
  • The wire protocol is loopback HTTP/JSON over an adb forward; the supported public interface for agents is the CLI surface and olef commands --json.
  • The net MITM proxy installs its CA into the device’s user trust store (net trust); apps that opt out of user CAs, pin certificates, or bypass the system store reject it, reported as tls_error. Forwarded bytes are never modified unless you explicitly intercept, rule, or replay.
  • The runtime attaches only to apps the OS marks debuggable (it goes through run-as), never through an app dependency. Its channel is an abstract unix socket that accepts only adbd’s uid and requires a per-attach token; runtime detach restores every hooked class.
  • On the host, the runtime and debug daemons take CLI requests over a 0600 unix socket, or on Windows over a loopback port that answers only connections presenting the daemon’s secret, kept in an owner-only file under ~/.olef.

Opt in to a local usage log with olef usage enable. Schema version 2 records only the command path, duration, CLI version, outcome, and typed error code/stage/retry posture — never argument values — and never uploads anything:

Terminal window
olef usage enable
olef usage report --days 30 | jq \
'{verbs, error_codes, error_stages, versions, recommendations, feedback_loop}'

Recommendations require repeated evidence: high error rates, slow p95s, or recurring error codes. The report suggests the next engineering action but does not edit code. Reproduce the evidence, add a regression, implement the change, then compare error rate and p95 by version.

why is non-mutating: it reads the on-device server only if it is already reachable and never installs, starts, or forwards anything to get a screen. collect is passive with respect to device lifecycle: the selected device/AVD must already be online, it only reads server-backed evidence through an already-established session, and it never starts an AVD, server, or adb forward. Its manifest records privacy status per artifact.

With --redact, device-scoped recovery commands use local @sd-… handles accepted by --device, or the selected project --target. Handle mappings live under ~/.olef/device-refs (0600 files in a 0700 directory on Unix). They work only on that host; deleting a mapping invalidates its handle. They are not credentials. Device details and application session identifiers remain redacted, and suggested follow-ups retain --redact. Internal lifecycle identities such as avd:TV-default are never emitted as ADB serial arguments.