Async Yandex Passport (mobile) auth library for Music Assistant providers
Project description
ya-passport-auth
Async Yandex Passport (mobile) authentication library for Music Assistant providers.
Features
- Two login methods — QR code scan and cookie-based login.
- Full token-derivation graph — x_token exchange, music_token refresh, Passport cookie refresh (redirect-following), Quasar CSRF, Glagol device token, account info.
- Security-first —
SecretStrredacts tokens in repr/str/format/tracebacks and blocks pickling; host allow-list with HTTPS-only enforcement; CSRF extraction; per-request rate limiting; response size caps; log redaction viaRedactingFilter. - Async-native — built on
aiohttpwithasyncio.Lock-protected rate limiter and connection management. - Strictly typed —
mypy --strictclean, PEP 561py.typedmarker. - Well tested — 221 tests, 97.8 % branch coverage.
Installation
pip install ya-passport-auth
Quick start
QR login
from ya_passport_auth import PassportClient
async def qr_login():
async with PassportClient.create() as client:
qr = await client.start_qr_login()
print(f"Scan QR: {qr.qr_url}")
creds = await client.poll_qr_until_confirmed(qr)
info = await client.fetch_account_info(creds.x_token)
print(f"Logged in as {info.display_login} (uid={info.uid})")
Cookie login
from ya_passport_auth import PassportClient
async def cookie_login():
cookies = "Session_id=...; sessionid2=..." # from browser
async with PassportClient.create() as client:
creds = await client.login_cookies(cookies)
print(f"x_token acquired, music_token ready")
Architecture
PassportClient (public facade)
├── SafeHttpClient (host allow-list, HTTPS enforcement, size caps, rate limiting)
│ └── AsyncMinDelayLimiter
└── Flows
├── QrLoginFlow → CSRF scrape → session create → poll → x_token
├── CookieLoginFlow → raw cookies → x_token
├── _token_exchange → cookies→x_token, x_token→music_token (shared)
├── PassportSessionRefresher → x_token → session cookies (follows redirects)
├── AccountInfoFetcher → x_token → uid/login/avatar
├── QuasarCsrfFetcher → CSRF token for IoT API
└── GlagolDeviceTokenFetcher → music_token → Glagol device token
API overview
PassportClient
| Method | Description |
|---|---|
start_qr_login() |
Begin QR login, returns QrSession |
poll_qr_until_confirmed(qr) |
Poll until scanned, returns Credentials |
complete_qr_login(qr) |
Exchange confirmed QR for tokens |
login_cookies(cookies) |
Exchange browser cookies for Credentials |
refresh_music_token(x_token) |
x_token → music_token |
refresh_passport_cookies(x_token) |
Refresh session cookies (follows redirect chain) |
get_quasar_csrf_token() |
Quasar CSRF token |
get_glagol_device_token(music_token, ...) |
Glagol device token |
fetch_account_info(x_token) |
Account metadata |
validate_x_token(x_token) |
Check if token is valid |
SecretStr
Opaque wrapper — repr() and str() return ***, pickling raises
TypeError. Access plaintext only via get_secret().
Credentials
Frozen, slotted dataclass returned by poll_qr_until_confirmed() and
login_cookies():
| Field | Type |
|---|---|
x_token |
SecretStr |
music_token |
SecretStr |
uid |
int | None |
login |
str | None |
Exception hierarchy
YaPassportError
├── NetworkError
│ └── UnexpectedHostError
└── AuthFailedError
├── InvalidCredentialsError
├── CsrfExtractionError
├── RateLimitedError
├── QRPendingError
└── QRTimeoutError
Security
- HTTPS-only —
_check_host()rejects any non-httpsURL, preventing protocol-downgrade attacks via redirectLocationheaders. - Host allow-list — every request is validated against a frozen set of allowed Yandex hosts. Redirect targets are checked at each hop.
- Token redaction —
SecretStrhides values inrepr/str/format;RedactingFilterscrubs OAuth headers and hex tokens from log output. - No pickling —
SecretStrandCredentialsblockpickle/copy. - Response size caps — 1 MiB for JSON, 2 MiB for HTML.
- See SECURITY.md for the full threat model (T1–T14).
Security disclaimer
This library interacts with Yandex Passport using public mobile OAuth client IDs and secrets extracted from official Yandex Android applications. These values are well-known and present in many open-source projects; they are treated here as constants, not secrets. Do not use this library for anything other than authenticating into your own Yandex account.
There is no official Yandex API for the mobile Passport flow. Endpoints, response shapes, and regex patterns may break without notice.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ya_passport_auth-1.2.2.tar.gz.
File metadata
- Download URL: ya_passport_auth-1.2.2.tar.gz
- Upload date:
- Size: 45.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f700ccd89dbf057e5601ebe24d1735a2d07be2806444f9e6c8c1f77ea0ed2291
|
|
| MD5 |
214daac8fa64f211ea412824cb390b55
|
|
| BLAKE2b-256 |
eb7a44f41c75272efdb370bc55aae6ce2326ca32ff4e1af285aa930cc23ffd19
|
Provenance
The following attestation bundles were made for ya_passport_auth-1.2.2.tar.gz:
Publisher:
release.yml on trudenboy/ya-passport-auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ya_passport_auth-1.2.2.tar.gz -
Subject digest:
f700ccd89dbf057e5601ebe24d1735a2d07be2806444f9e6c8c1f77ea0ed2291 - Sigstore transparency entry: 1280192089
- Sigstore integration time:
-
Permalink:
trudenboy/ya-passport-auth@cfaa141af01168a20651be244ad67a34d23c3b99 -
Branch / Tag:
refs/tags/v1.2.2 - Owner: https://github.com/trudenboy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cfaa141af01168a20651be244ad67a34d23c3b99 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ya_passport_auth-1.2.2-py3-none-any.whl.
File metadata
- Download URL: ya_passport_auth-1.2.2-py3-none-any.whl
- Upload date:
- Size: 32.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab09714d5885561d0e4ea405aaa65d7580e203c62c891f06947990b9c7845ed7
|
|
| MD5 |
1f5061a62e2e482b6020e53a620e6af6
|
|
| BLAKE2b-256 |
7f5f907041940511b60bf220c2eac24e9884d822189db6580342017b7968008f
|
Provenance
The following attestation bundles were made for ya_passport_auth-1.2.2-py3-none-any.whl:
Publisher:
release.yml on trudenboy/ya-passport-auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ya_passport_auth-1.2.2-py3-none-any.whl -
Subject digest:
ab09714d5885561d0e4ea405aaa65d7580e203c62c891f06947990b9c7845ed7 - Sigstore transparency entry: 1280192094
- Sigstore integration time:
-
Permalink:
trudenboy/ya-passport-auth@cfaa141af01168a20651be244ad67a34d23c3b99 -
Branch / Tag:
refs/tags/v1.2.2 - Owner: https://github.com/trudenboy
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@cfaa141af01168a20651be244ad67a34d23c3b99 -
Trigger Event:
push
-
Statement type: