Skip to main content

cookietuner

Extract and display cookies from macOS browsers.
Decrypts Chrome's macOS Keychain entries, parses Safari's binary cookie store, and captures fresh sessions from a throwaway Chrome sign-in.

GitHub · Sponsor

PyPI License Stars


Get Started

Run without installing:

uvx cookietuner

Or install permanently:

uv tool install cookietuner

What is cookietuner?

A command-line tool that reads cookies straight from your local macOS browser stores. It decrypts Chrome's encrypted cookie database via the macOS Keychain (Chrome 130+ format) and parses Safari's binary Cookies.binarycookies file directly, with no extensions involved.

When a store can't give you what you need, cookietuner capture opens a clean Chrome window instead, waits while you sign in yourself, and keeps the cookies that session set.

Features

  • Chrome support — decrypts cookies using macOS Keychain, Chrome 130+ format.
  • Safari support — parses the binary cookies format with SameSite detection.
  • Throwaway sign-in capture — a fresh Chrome profile, deleted afterwards, for session and HttpOnly cookies that never reach disk.
  • Flexible completion conditions — finish on cookie names or globs, on a cookie's value, on the page URL, or on your own predicate, with a settle window for cookies that arrive late.
  • Chunked cookies — matches a cookie split into name.0, name.1, … and reassembles it on request.
  • Sign in from the Passwords app — optionally loads Apple's iCloud Passwords extension, so nothing is typed.
  • Multiple output formats — table, short, line, and JSON.
  • Domain filtering — filter by exact domain (x.com matches .x.com, not api.x.com or dropbox.com), several at once when capturing.
  • Profile selection — choose which browser profile to read from.
  • Cookie metadata — expiration, Secure, HttpOnly, and SameSite flags.
  • Python API — capture and capture_async, with an exception and exit code per failure.

Usage

List cookies

# Chrome cookies (browser flag is required)
cookietuner cookies -b chrome

# Safari cookies
cookietuner cookies -b safari

# Filter by domain
cookietuner cookies -b chrome -d google.com

# Pick a Chrome profile
cookietuner cookies -b chrome -p "Profile 1"

Output formats

Format Flag Use case
Full table (default) -o table Browsing all cookie details
Short table -o short Just domain, name, value
Line -o line Space-separated, for shell scripting
JSON -o json Piping into jq or another tool

Capture a fresh session

Opens Chrome on a temporary profile with none of your history or logins. You sign in by hand; cookietuner never types, fills or sees your credentials. The profile is deleted when the capture ends, including on timeout, Ctrl-C or error.

# Wait for specific cookies, then print them and close the browser
cookietuner capture --url https://example.com/login \
  -d example.com --until session_id --until csrf_token -o json

# Without any condition, the capture ends when you close the browser
cookietuner capture --url https://example.com/login -d example.com

# Sign in from the Passwords app instead of typing
cookietuner capture --url https://example.com/login \
  -d example.com --until session_id --passwords

# Route the session through a proxy
cookietuner capture --url https://example.com/login \
  -d example.com --proxy socks5://127.0.0.1:1080

Deciding when it's done

A capture finishes once every condition you gave holds at the same time. Without any, it ends when you close the browser.

Option Waits for
--until name A cookie name, a glob (--until 'sb-*-auth-token'), or a complete chunk set (name.0, name.1, …). Repeatable
--until-value 'uid!=anon_*' A cookie to exist and its value to match, or with != to stop matching. Repeatable. This is what tells a signed-in session from an anonymous one that reuses the name
--until-url '*/dashboard*' An open page's URL to match; with a leading !, for no page to match, so you can wait to leave /login
--settle 2 Keeps polling for 2 more seconds once everything holds, so late cookies, trailing chunks and post-login redirects land
--timeout 120 Caps the whole wait (300 seconds by default)

-d repeats too, for a sign-in that spans domains:

cookietuner capture --url https://example.com/login \
  -d example.com -d auth.example.com \
  --until 'sb-*-auth-token' --until-value 'uid!=anon_*' \
  --until-url '*/dashboard*' --settle 2 -o json

Closing the window, quitting Chrome with Cmd+Q and Chrome exiting on its own all mean the same thing: the capture keeps the last snapshot taken before the end. If conditions were given and that snapshot doesn't satisfy them, it fails and names what was missing rather than returning a half-signed-in session. What it's still waiting for is printed to stderr as it goes, and values and live URLs never are.

Cookie values go to stdout on their own and progress goes to stderr, so the output pipes straight into a secret store:

cookietuner capture --url https://example.com/login \
  -d example.com --until session_id -o json | my-secret-store put example-session

This reaches cookies a store reader can't: session cookies, cookies kept only in memory, and HttpOnly cookies on a macOS version that denies access to Chrome's own store.

Note --passwords is the only option that reads your Chrome profile folder, to copy the extension out of it. macOS withholds that folder until the program running cookietuner has Full Disk Access (System Settings > Privacy & Security), and without it the capture fails with ProfileAccessDenied. Capturing without --passwords needs no access at all.

Use from Python

The same capture, as a function, with the same conditions behind both:

from cookietuner import CaptureTimeout, capture, join_chunks

cookies = capture(
    url="https://example.com/login",
    domains={"example.com", "auth.example.com"},
    until={"sb-*-auth-token"},
    until_values=["uid!=anon_*"],
    until_url="*/dashboard*",
    settle=2,
    on_progress=lambda pending: print("waiting for", pending),
)

for cookie in cookies:                      # each a Cookie model
    print(cookie.domain, cookie.name, cookie.is_httponly)

token = join_chunks(cookies, "sb-abcdef-auth-token")

until also takes a predicate (until=lambda cs: ...), called on each poll with the cookies that would be returned, for anything the flags can't express. capture_async is the same function for an async application.

Failures raise CaptureTimeout, CaptureIncomplete, ChromeNotFound, ProfileAccessDenied or PasswordsExtensionMissing, all subclasses of CaptureError, each carrying the CLI's exit code as exc.exit_code. Full signatures, condition semantics and exit codes are in the API reference.

List browser profiles

# All profiles
cookietuner profiles

# Filter by browser
cookietuner profiles -b chrome

Requirements

  • macOS (the tool reads macOS-specific cookie stores).
  • Python 3.11+.
  • Chrome and/or Safari.

Development

git clone https://github.com/alltuner/cookietuner.git
cd cookietuner
uv sync
uv run pytest
uv run cookietuner

The tests marked browser drive a real Chrome. Locally they run it headless, so the suite doesn't steal focus; CI runs them with a real window, which is what a capture actually opens. To watch one happen:

COOKIETUNER_TEST_HEADLESS=0 uv run pytest -m browser

# Or skip them entirely, where there's no desktop session
uv run pytest -m "not browser"

License

MIT

Support the project

cookietuner is an open source project built by David Poblador i Garcia through All Tuner Labs.

If this project was useful to you, consider supporting its development.


Built by David Poblador i Garcia with the support of All Tuner Labs.
Made with ❤️ in Poblenou, Barcelona.

Metadata

Release files for cookietuner 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cookietuner 0.3.1
File Size Uploaded
cookietuner-0.3.1.tar.gz 25.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cookietuner 0.3.1
File Interpreter ABI Platform
cookietuner-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 53.9 kB

Release files / cookietuner-0.3.1.tar.gz

Download URL cookietuner-0.3.1.tar.gz
Size 25.3 kB
Tags Source
SHA-256 checksum
How to use checksums
27996748cf8b4d46c28565191791e8d59fad9540e5f5e4fea472dec773ed6caf
BLAKE2b-256 checksum
How to use checksums
16d125bb9998441e84b34b844a787e2296ef528cbd5f984aed8a838b2cbdbcbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / cookietuner-0.3.1-py3-none-any.whl

Download URL cookietuner-0.3.1-py3-none-any.whl
Size 28.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f287ebb12624655c589e772e847f7ebbfd30c18df5967d60a247160f2eefe98
BLAKE2b-256 checksum
How to use checksums
325ca5e770ac946b9e4aea349d314879acd2e611241de229f51375d7a49f2b2e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.3.2

2 release files

This release

0.3.1 This release

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page