🎭 msauth-browser
Extract Microsoft OAuth tokens using Playwright browser automation.
Microsoft Graph API requires a valid OAuth access token to perform delegated actions like sending emails, reading mailboxes, or enumerating users. Getting that token programmatically is surprisingly painful: MSAL requires localhost redirect URIs, and pure API flows cannot handle MFA prompts, Conditional Access policies, or CAPTCHAs.
msauth-browser solves this by driving a real Chromium browser through the full OAuth 2.0 authorization code flow with PKCE. It handles any interactive challenge exactly as a legitimate user would, and gives you back a ready-to-use access token (and refresh token) that you can feed into your scripts and tooling.
[!TIP] Pair with ROADtools or GraphSpy for downstream enumeration and exploitation using the acquired tokens.
🎯 Why This Tool?
- Real browser, real auth: navigates MFA, Conditional Access, device compliance checks, and CAPTCHAs that API-only tools cannot handle.
- No localhost redirect required: unlike MSAL, works with any redirect URI, including first-party Microsoft app URIs.
- First-party app presets: authenticate as Graph Explorer, Teams, Outlook, etc. to leverage their pre-approved scopes.
- PRT cookie injection: inject an
x-ms-RefreshTokenCredentialcookie for SSO-based login, bypassing credential prompts entirely. - ROADtools integration: save tokens in
.roadtools_authformat for downstream use with ROADtools or GraphSpy, with optional auto-refresh.
📦 Installation
Prefer using uv, a fast Python package manager that installs tools in isolated environments. Alternatively, pipx or pip work as well.
With uv (recommended)
uv tool install persistently installs the tool and adds it to your PATH:
From PyPI:
uv tool install msauth-browser
From GitHub (latest):
uv tool install git+https://github.com/n3rada/msauth-browser.git
To upgrade later:
uv tool upgrade msauth-browser
[!TIP] You can also run it without installing using
uvx:uvx msauth-browser --help uvx --from git+https://github.com/n3rada/msauth-browser.git msauth-browser --help
With pipx or pip
pipx install msauth-browser
# or from GitHub
pipx install "git+https://github.com/n3rada/msauth-browser"
pip install msauth-browser
# or from GitHub
pip install "git+https://github.com/n3rada/msauth-browser"
🎭 Playwright
Ensure the Chromium browser is available:
playwright install chromium
If installed with uv tool install:
uv tool run --from msauth-browser playwright install chromium
If installed with pipx:
& "$(pipx environment --value PIPX_LOCAL_VENVS)\msauth-browser\Scripts\playwright.exe" install chromium
If you are in a corporate environment with TLS inspection (e.g., using Zscaler), disable certificate verification first:
$env:NODE_TLS_REJECT_UNAUTHORIZED = "0"
🧸 Usage
msauth-browser [config] [options]
The default configuration is graph (Graph Explorer). Available presets:
| Preset | Application |
|---|---|
graph |
Graph Explorer |
outlook |
Outlook |
teams |
Microsoft Teams |
powerapps |
Power Apps |
powerautomate |
Power Automate |
📋 Examples
# Default: authenticate as Graph Explorer
msauth-browser
# Authenticate as Microsoft Teams
msauth-browser teams
# Request additional Mail.Send scope on Graph Explorer
msauth-browser --add-scope "https://graph.microsoft.com/Mail.Send"
# Use a PRT cookie for SSO (headless, no visible browser)
msauth-browser --headless --prt-cookie "<x-ms-RefreshTokenCredential>"
# Save tokens in ROADtools format with auto-refresh
msauth-browser --save roadtools --refresh
⚙️ Options
| Flag | Description |
|---|---|
--add-scope <scope> |
Additional OIDC scope(s) to request |
--prt-cookie <JWT> |
x-ms-RefreshTokenCredential PRT cookie for SSO |
--headless |
Run the browser in headless mode |
--save [roadtools] |
Persist tokens (currently supports roadtools format) |
--refresh |
Auto-refresh the access token before expiry (requires --save) |
--log-level <LEVEL> |
Set log verbosity (TRACE, DEBUG, INFO, WARNING, ERROR, CRITICAL) |
-V, --version |
Show version and exit |
🔑 About the PRT Cookie
The PRT cookie is officially x-ms-RefreshTokenCredential and it is a JSON Web Token (JWT). The actual Primary Refresh Token (PRT) is encapsulated within the refresh_token field, which is encrypted by a key under the control of Entra ID, rendering its contents opaque.
It can be used as a cookie wired to login.microsoftonline.com to authenticate and skip credential prompts entirely.
🏢 Microsoft First-Party Apps
Microsoft first-party apps have hardcoded, pre-approved scopes.
You cannot simply add ChannelMessage.Read.All to the scope parameter of the Teams application, the request will fail. Use --add-scope only with scopes that are valid for the selected app configuration.
❓ Why Not MSAL?
One major limitation is that MSAL requires localhost redirect URIs.
It also does not support injecting PRT cookies into the authentication flow.
🧩 Adding New App Presets
- Drop a JSON file into
msauth_browser/configs/. - Provide the required fields:
nameclient_idredirect_uridefault_scopes(array of scopes), optional; if omitted or empty, defaults toopenidandoffline_access.
- Optionally include a
slugfield; otherwise the filename (without extension) becomes the lookup key.
🤝 Contributing
Contributions are welcome and appreciated! Whether it is fixing bugs, adding new app presets, improving the documentation, or sharing feedback, your effort is valued and makes a difference.
Open-source thrives on collaboration and recognition. Contributions, large or small, help improve the tool and its community. Your time and effort are truly valued.
🙏 Acknowledgments
- Browser automation powered by Playwright.
- PKCE flow handled by pkce.
- Token persistence format compatible with ROADtools by @_dirkjan.
- Logging powered by Loguru.
⚠️ Disclaimer
This tool is provided strictly for defensive security research, education, and authorized penetration testing. You must have explicit written authorization before running this software against any system you do not own.
This tool is designed for educational purposes only and is intended to assist security professionals in understanding and testing the security of Microsoft Entra ID environments in authorized engagements.
Acceptable environments include:
- Private lab environments you control (local VMs, isolated networks).
- Sanctioned learning platforms (CTFs, Hack The Box, OffSec exam scenarios).
- Formal penetration-test or red-team engagements with documented customer consent.
Misuse of this project may result in legal action.
⚖️ Legal Notice
Any unauthorized use of this tool in real-world environments or against systems without explicit permission from the system owner is strictly prohibited and may violate legal and ethical standards. The creators and contributors of this tool are not responsible for any misuse or damage caused.
Use responsibly and ethically. Always respect the law and obtain proper authorization.
Metadata
Release files for msauth-browser 0.2.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| msauth_browser-0.2.7.tar.gz | 12.6 kB | Without provenance | Details for msauth_browser-0.2.7.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| msauth_browser-0.2.7-py3-none-any.whl | Python 3 | none | any | Details for msauth_browser-0.2.7-py3-none-any.whl |
Total release size: 29.9 kB
Release files / msauth_browser-0.2.7.tar.gz
| Download URL | msauth_browser-0.2.7.tar.gz |
|---|---|
| Size | 12.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9c08c5ebc551876bdf7475c045e0ea1c79e39a76e3dcdd80f335e6f61406821a
|
|
BLAKE2b-256 checksum How to use checksums |
4e5b249e2321ae74b567ac23a711b225583f81a5f31cbde3376577bad4921cc8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":null,"id":"forky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / msauth_browser-0.2.7-py3-none-any.whl
| Download URL | msauth_browser-0.2.7-py3-none-any.whl |
|---|---|
| Size | 17.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7ee6771c1ba5b696214337463e9117b119fa576cf63d580a715d549d10622a77
|
|
BLAKE2b-256 checksum How to use checksums |
fcc8dab5bef6cdb160cd44614b71c18d79026a87d124c93b3fa6e806cf03a71c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":null,"id":"forky","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for msauth-browser 0.2.7
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.