Desktop multi-account token manager for Microsoft 365 / Microsoft Graph. Store refresh tokens, mint fresh access tokens, track expiry, and bulk-refresh expired accounts — all from a dark green UI.
- Multi-account vault — manage many M365 accounts in one window
- Public-client flow — works with device-code / ADFT-style tokens (no client secret, no tenant field)
- One-click exchange — refresh token → new access token via
login.microsoftonline.com/common - Auto-clean tokens — strips whitespace, quotes, and accidental double-pastes (fixes
AADSTS9002313) - Scope fallback — retries with
https://graph.microsoft.com/.defaulton malformed/invalid scope - Import panel — paste a raw session dump; Client ID / tokens / scopes are parsed automatically
- Bulk refresh — refresh all expired or expiring access tokens in one go
- Optional encryption — master-password vault using Fernet + PBKDF2 (requires
cryptography) - Copy access token — one click (or double-click an account in the list)
| Item | Notes |
|---|---|
| Python | 3.8+ |
| tkinter | Usually bundled; on Debian/Ubuntu: sudo apt install python3-tk |
| cryptography (optional) | pip install cryptography for encrypted-at-rest storage |
git clone https://github.com/iRichNode/o365TokenGen.git
cd o365TokenGen
# optional encrypted vault
pip install -r requirements.txt
python main.pyOn Linux without Tk:
sudo apt update
sudo apt install python3-tk
python main.py- Click ADD ACCOUNT
- Fill in:
- Account name — e.g.
user@contoso.com - Client ID — the Azure app ID that issued the refresh token (e.g. Microsoft public clients)
- Scope — default
https://graph.microsoft.com/.defaultis fine for most cases - Refresh token — paste via PASTE REFRESH, or dump a full panel with IMPORT PANEL
- Account name — e.g.
- Click GET NEW ACCESS TOKEN
- Use COPY ACCESS TOKEN when you need the bearer token
Keyboard: Ctrl+Enter also triggers token exchange.
The app always uses the public-client refresh grant against the common authority:
POST https://login.microsoftonline.com/common/oauth2/v2.0/token
grant_type=refresh_token
client_id=<your client id>
refresh_token=<cleaned refresh token>
scope=<scope or .default>
No client_secret is sent. Rotated refresh tokens returned by Azure are saved automatically.
| Path | Purpose |
|---|---|
~/.o365tokengen.db |
SQLite database (WAL mode) of accounts + optional vault settings |
If you set a master password, refresh/access tokens are encrypted with Fernet (key derived via PBKDF2-HMAC-SHA256, 310k iterations). Without a master password, tokens are stored in plaintext on disk — use encryption if the machine is shared.
| Control | Action |
|---|---|
| ADD ACCOUNT / DELETE | Manage the account list |
| IMPORT PANEL | Parse clipboard session dump |
| PASTE REFRESH | Paste + clean a refresh token |
| .default | Reset scope to Graph .default |
| SAVE ACCOUNT | Persist current form |
| GET NEW ACCESS TOKEN | Exchange refresh → access |
| REFRESH ALL EXPIRED | Bulk exchange for missing/expiring tokens |
| MASTER PASSWORD | Set / change / remove vault encryption |
| t.me/iRichNodes | Opens the author’s Telegram (clickable in title bar & status bar) |
| Code | Meaning / fix |
|---|---|
AADSTS9002313 |
Malformed request — app auto-cleans whitespace & double-paste; re-copy token if it persists |
AADSTS70011 |
Bad scope — click .default and retry |
AADSTS700082 / 700081 |
Refresh token expired or revoked — capture a new session |
AADSTS7000218 |
Wrong client_id for that token |
AADSTS65001 |
Consent missing for the requested scope |
AADSTS50076 |
MFA / interactive re-auth required |
o365TokenGen/
├── main.py # full application
├── requirements.txt # optional deps
├── LICENSE
└── README.md
This tool is intended for authorized security testing, red-team labs, and administration of accounts you own or have explicit permission to access. Misuse against third-party tenants without authorization may violate law and Microsoft terms of service. You are solely responsible for how you use it.
iRichNode
- Telegram: https://t.me/iRichNodes
MIT — see LICENSE.