restAD
A read-only REST interface over the msad
Active Directory library, built with FastAPI + Pydantic, managed with
uv on Python 3.14.
Only LDAP search operations are exposed. No write operations (create / modify / delete / password reset / group membership changes) are reachable through the API.
How configuration is resolved
The effective connection config (an msad.DomainConfig) is built in two layers,
with the environment always winning:
- msad TOML file (optional) —
~/.msad.tomlby default, or the path inMSAD_CONFIG_FILE. TheMSAD_DOMAINvariable selects which[domains.<name>]section to use (otherwise the[defaults] domain). MSAD_*environment overrides — applied on top of the TOML values.
This lets you keep non-secret settings in the TOML file (or omit it entirely) and inject credentials and any connection parameter at runtime via the environment, so secrets never need to live on disk.
Environment variables
| Variable | Overrides / effect |
|---|---|
MSAD_CONFIG_FILE |
Path to the msad TOML file (default ~/.msad.toml). |
MSAD_DOMAIN |
Which [domains.<name>] section to use. |
MSAD_HOST |
Directory host (e.g. dc.example.com). |
MSAD_BASE |
Search base DN (e.g. dc=example,dc=com). |
MSAD_PORT |
Port (int, e.g. 636). |
MSAD_USE_SSL |
LDAPS on/off (true/false/1/0/yes/no). |
MSAD_USER |
Bind user. Setting user and password enables simple bind. |
MSAD_PASSWORD |
Bind password. |
MSAD_QUERY_TIMEOUT |
Per-operation receive timeout in seconds (int). |
host and base are required (from either the TOML file or the environment).
Authentication:
- Omit
MSAD_USER/MSAD_PASSWORDand leave them unset in the TOML → Kerberos/SASL bind (runkinitfirst). - Set both
MSAD_USERandMSAD_PASSWORD→ simple user/password bind.
Server variables
| Variable | Effect |
|---|---|
RESTAD_HOST |
HTTP bind host for the restad command (default 127.0.0.1). |
RESTAD_PORT |
HTTP bind port (default 8000). |
RESTAD_LAZY_CONNECT |
If true, start even if the directory is unreachable at boot. |
Install
uv sync
The msad dependency is pulled from PyPI (msad>=0.8). Because msad depends
on gssapi, installing it builds a C extension against the system Kerberos
libraries, so you need the krb5 development headers available (e.g.
libkrb5-dev + krb5-config on Debian/Ubuntu, krb5 via Homebrew on macOS).
Common developer tasks run through the Makefile:
make sync # install/refresh the dev environment
make lint # ruff check + format check
make test # run the test suite
make build # build wheel + sdist into dist/
make publish # upload to PyPI (needs credentials)
Run
Credentials are passed via the environment:
export MSAD_HOST=dc.example.com
export MSAD_BASE='dc=example,dc=com'
export MSAD_PORT=636
export MSAD_USE_SSL=true
export MSAD_USER='svc_reader'
export MSAD_PASSWORD='s3cr3t'
uv run restad
# or:
uv run uvicorn restad.app:app --host 0.0.0.0 --port 8000
Then open the interactive docs at http://127.0.0.1:8000/docs.
Endpoints (all read-only)
GET /health— connectivity probe (connect/bind test).- Users —
GET /users(by field),/users/inactive,/users/{id},/users/{id}/groups,/users/{id}/status,/users/{id}/disabled,/users/{id}/locked. - Computers —
GET /computers(by field),/computers/stale,/computers/domain-controllers,/computers/os-summary,/computers/{id}. - Groups —
GET /groups(search),/groups/empty,/groups/{id},/groups/{id}/members,/groups/{id}/members/{user}(membership check). - OUs —
GET /ous(find),/ous/contents?ou_dn=...,/ous/{id}. - Audit —
GET /audit/domain,/audit/password-policy,/audit/password-policy/violations,/audit/privileged-groups,/audit/fsmo-roles,/audit/trusts,/audit/sites,/audit/gpos,/audit/gpos/{id},/audit/fine-grained-password-policies.
Notes
- LDAP entries are dynamic (attributes depend on what the directory returns),
so entries are serialized as open JSON objects inside typed envelopes
(
count+entries, orentry). - A single LDAP connection is opened during the app lifespan and shared across requests; it is unbound at shutdown.
Metadata
Release files for restad 0.1.0
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 | |
|---|---|---|---|---|
| restad-0.1.0.tar.gz | 26.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| restad-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.7 kB
Release files / restad-0.1.0.tar.gz
| Download URL | restad-0.1.0.tar.gz |
|---|---|
| Size | 26.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0af227505f65f72c4cff536e40b63fd9cae64aecb2217da6c28905e1d8f3ce8e
|
|
BLAKE2b-256 checksum How to use checksums |
0ddcfcd674af701c48cd356f1f2644971baeb490d4f66a2b778b4cd30c1751db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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 / restad-0.1.0-py3-none-any.whl
| Download URL | restad-0.1.0-py3-none-any.whl |
|---|---|
| Size | 29.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e596bb3044fbab72848aee2f0cff54b63f61d790e46518b73a9cb2180202dd49
|
|
BLAKE2b-256 checksum How to use checksums |
6bf9fe420e337898c87184ca8ae9b26b98842a08784ad360bdee0b2bb1c73e06
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","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}
|
Security for restad 0.1.0
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.