Skip to main content

Official-API-only, BYOK CLI for researching Reddit and YouTube with your own API keys and a tamper-evident, hash-chained audit log.

Project description

auditreach-cli (Python)

Official-API-only, BYOK CLI and library for researching Reddit and YouTube with your own API keys and a tamper-evident, hash-chained audit log -- built for AI agents and compliance teams that can't rely on cookie-based scraping or shared credential pools.

PyPI version License: Apache 2.0 Python versions CI npm version

Why this exists

auditreach talks to Reddit and YouTube only through their official, documented APIs, using your own API keys -- never a shared pool -- and every single query writes a hash-chained entry to a local audit log: which platform, which endpoint, which scope, and a plain-language line explaining the consent/ToS basis for that specific call. No cookie import, no session-token reuse, no code path that could pretend to be a logged-in human. See the project README for the full compliance rationale. This package is the Python distribution -- a genuine, independent port of the npm CLI's logic, not a wrapper around the Node binary.

Install

pip install auditreach-cli

or with uv:

uv add auditreach-cli

The complementary JS/TS distribution installs the same way on the npm side: npm install -g auditreach-cli (or npx auditreach-cli search ... to run it once without installing) -- see the project README for that package. Both are first-class, maintained together; neither is deprecated in favor of the other.

Quickstart

1. Set up credentials for the platform you want to search (BYO-key -- your own, never shared):

auditreach auth --platform reddit
# Prompts for Client ID, Client secret, username, password.
# Create a script-app at https://www.reddit.com/prefs/apps first.

auditreach auth --platform youtube
# Prompts for an API key.
# Create one at https://console.cloud.google.com/apis/credentials

By default, credentials are stored in your OS keychain via the keyring package (Keychain on macOS, Credential Manager on Windows, Secret Service/kwallet on Linux) -- the Python-ecosystem equivalent of the npm package's @napi-rs/keyring dependency. This port additionally checks a platform-specific environment variable first (AUDITREACH_REDDIT_CLIENT_ID, AUDITREACH_REDDIT_CLIENT_SECRET, AUDITREACH_REDDIT_USERNAME, AUDITREACH_REDDIT_PASSWORD, AUDITREACH_YOUTUBE_API_KEY), falling back to the keychain when unset -- a deliberate addition beyond the npm package's keychain-only design, since a headless CI runner or an agent sandbox often has no interactive prompt and no keychain daemon running at all. Nothing is ever hardcoded either way; see docs/concepts.md for the full precedence rule.

2. Search:

auditreach search --platform reddit --query "your query" --subreddit some_subreddit
auditreach search --platform youtube --query "your query" --channel @SomeChannel

Real output:

AuditReach v0.1 -- Official-API Research CLI
Platform: Reddit  |  Auth: OAuth script-app grant, read-only, public-subreddit scope

Fetching... (official API, rate-limit aware)
✓ 14 results returned (Reddit API Terms -- public content, official API, read-only script-app credentials)

RESULTS (14)
[1] "How are people testing for memory poisoning in long-running agents?"
    u/some_researcher · 2026-07-05T14:22:00.000Z
    https://reddit.com/r/MachineLearning/comments/...
...

Audit log entry written: ar_2026-07-16_9f3c2a
Consent basis: Reddit API Terms -- public content, official API, read-only script-app credentials
Full results: ./auditreach-results-2026-07-16.json
Full audit trail: ./auditreach.log.jsonl

3. Verify the audit log has not been tampered with:

auditreach verify-log
Verifying ./auditreach.log.jsonl...
✓ Chain intact: 14 entries, no gaps, no tampering detected.

Using the library instead of the CLI

from auditreach import RedditClient, get_reddit_credentials, RedditSearchOptions

credentials = get_reddit_credentials()
if credentials is None:
    raise SystemExit("run `auditreach auth --platform reddit` first")

outcome = RedditClient(credentials).search(
    RedditSearchOptions(query="agent memory poisoning", subreddit="MachineLearning")
)
for item in outcome.items:
    print(item.title, item.url)
from auditreach import verify_audit_log_chain

result = verify_audit_log_chain()
if not result.valid:
    print(f"Chain broken at entry {result.broken_at_index}: {result.reason}")

The Python library API uses idiomatic snake_case attribute names (created_at, client_secret, broken_at_index, ...); the on-the-wire JSON this CLI writes (the audit log file, --output results files, and --json stdout output) uses the same field names the npm package's JSON output uses, so a script or agent parsing either CLI's output sees identical keys.

Commands

auditreach has three subcommands, matching the npm CLI's flags exactly.

auditreach search

Flag Description
--platform <platform> reddit | youtube (required)
--query <query> search query
--subreddit <subreddit> restrict search to one subreddit (Reddit only)
--channel <handle> restrict search to one channel, e.g. @AnthropicAI (YouTube only)
--since <date> only results published after this date, e.g. 2026-06-01 (YouTube only)
--max-results <n> maximum results to return (default: 25; platform caps: 100 Reddit / 50 YouTube)
--before <fullname> page results before this Reddit fullname cursor, e.g. t3_abc123 (Reddit only)
--after <fullname> page results after this Reddit fullname cursor, e.g. t3_abc123 (Reddit only)
--output <path> write full results JSON to this path
--json print structured JSON to stdout instead of human-readable output, for scripts and agent callers

auditreach auth

Flag Description
--platform <platform> reddit | youtube (required)
--clear delete stored credentials for this platform
--verify verify stored credentials are valid without running a search (no results file, no audit-log entry)
--json print structured JSON to stdout instead of human-readable output

auditreach verify-log

Flag Description
--path <path> path to the audit log file (defaults to ./auditreach.log.jsonl if omitted)
--json print structured JSON instead of human-readable output

Run auditreach <command> --help any time to see the exact flags your installed version supports.

How the hash chain works

Every entry in auditreach.log.jsonl is hash-chained -- each entry's hash is computed from a canonical (recursively key-sorted) JSON serialization of its own content, and the next entry references the previous entry's hash via prev_entry_hash. verify-log re-derives every entry's hash from its stored content and checks it against the stored entry_hash, then checks every prev_entry_hash link against the actual previous entry. Either check failing (a hand-edited field, a deleted entry, a reordered entry) breaks the chain at an identifiable index. This is a faithful port of the same algorithm (SHA-256 over canonical JSON, the same chain-link field) the npm package's src/audit-log/ modules implement -- see docs/concepts.md for the full data model, and tests/test_hash_chain.py in this package for the tamper-detection tests (a mutated entry, a broken chain link, and a deleted middle entry are each caught and pinpointed).

Platform coverage

Same as the npm package: Reddit (OAuth2 password grant, direct REST calls via the stdlib urllib instead of a third-party HTTP library) and YouTube (YouTube Data API v3, called directly over REST instead of pulling in Google's full google-api-python-client SDK and its own dependency chain) are shipped. X (Twitter) is not yet shipped in either distribution -- see the project README for why. auditreach-cli's only runtime dependency is keyring.

Security

See SECURITY.md for the vulnerability disclosure policy. Credentials are never logged, printed, or written to the audit log -- only a 6-character SHA-256 fingerprint of the credential used for a given query appears there. No eval/exec of anything read from user input or an API response, no shell/subprocess calls, and no third-party HTTP library in the request path (stdlib urllib only).

Contributing

See CONTRIBUTING.md for the full guide, covering both the TypeScript and Python codebases.

cd python
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

License

Apache 2.0, see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

auditreach_cli-0.1.0.tar.gz (35.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

auditreach_cli-0.1.0-py3-none-any.whl (32.1 kB view details)

Uploaded Python 3

File details

Details for the file auditreach_cli-0.1.0.tar.gz.

File metadata

  • Download URL: auditreach_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 35.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for auditreach_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 051629c1cca6c3a1447569c81f9b2693fad9f2c1d1fcffa43b06b315e66f261d
MD5 b6c4e8a14ea0c2d7f54f2dc36f3c9a7f
BLAKE2b-256 f58fde8edf51cf039b2f8388a937fc336c310088e235137988f6a8dde9c25f34

See more details on using hashes here.

File details

Details for the file auditreach_cli-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: auditreach_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 32.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for auditreach_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d59c14bfee4b458f5cee6b6ab1c7bd8ab5f7f537b6c68c8de9e0f3931745063e
MD5 a4cd7ad11d6b62dcec9394b3b4d53e39
BLAKE2b-256 e758d92b9332352cc551daec68801b5da3543be643bf625ed2aec00dc7cc3efd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page