Metadata-Version: 2.4
Name: multipass-auth
Version: 0.0.2
Summary: Reusable browser-login building blocks: credential resolution, persistent browser contexts, branded config, and a recogniser-loop auth engine
Author: Jei Blanchard
License-Expression: GPL-3.0-or-later
Project-URL: Homepage, https://github.com/doctorjei/multipass-auth
Project-URL: Source, https://github.com/doctorjei/multipass-auth
Project-URL: Issues, https://github.com/doctorjei/multipass-auth/issues
Keywords: authentication,credentials,playwright,sso
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: playwright>=1.40
Requires-Dist: duo-pass>=0.0.2
Dynamic: license-file

# multipass-auth

Reusable browser-login building blocks, spun out of
[canvasser](https://github.com/doctorjei/canvasser). Import name is
`multipass`; the distribution is `multipass-auth` (the bare name is a
decade-old stub on PyPI). GPL-3.0-or-later.

Ships four modules: **credential resolution** (`multipass.credentials`),
**persistent browser contexts** with 700/600 debug snapshots (`multipass.browser`),
a **branding skeleton** (`multipass.config` — state layout plus every brandable
string in one frozen object), and the **recogniser-loop auth engine**
(`multipass.auth`: `LoginState` dispatch, one IdP row, structural rejection
check, allowlist liveness) with Duo answered through the `duo-pass`
dependency. Factor plugins beyond Duo arrive through `extra_recognisers`.

```python
from pathlib import Path
from multipass import CredentialNames, resolve_credentials

NAMES = CredentialNames(
    username_vars=("CONCURRER_USERNAME",),
    password_vars=("CONCURRER_PASSWORD",),
    program="concurrer",
)

user, pw = resolve_credentials(
    names=NAMES,
    default_file=Path.home() / ".local" / "state" / "concurrer" / "secrets.env",
)
```

## Branding

A library must not hardcode its first host's variable names — and it must not
hold them as setup either. Every variable, flag example, and program name the
package can utter arrives per call, in one frozen `CredentialNames` the host
constructs and passes in (`resolve_credentials(names=...)`,
`LoginTarget(names=...)`). There is no `configure()`, no active branding, and
no default to inherit: a default here would be the thing every host silently
inherits. The `MULTIPASS_*` object exists only so the shape has something to
show, not something to run under. State paths work the same way:
`resolve_state_dir(config)` takes its `AuthConfig` explicitly, and the
browser's snapshot directory, session file, and profile dir are required
arguments wherever they are used.
