Async user / group / permission management library backed by a Rust core (SQLite, Argon2, JWT, optional HTTP relay)
Project description
user-permission-py
ユーザーとグループを管理するための非同期ライブラリ user-permission の Python バインディング です。
Rust 実装本体は別リポジトリに分離されました: mokuichi147/user-permission
このリポジトリは PyO3 + maturin による薄いラッパーのみを含み、PyPI パッケージ user-permission をビルド・公開します。
クイックスタート (サーバーを試す)
インストール不要で、uvx から直接サーバーを起動できます。
uvx user-permission serve --webui
ブラウザで http://127.0.0.1:8000/ui を開くと Web 管理画面が利用できます。 オプション一覧は サーバー起動 を参照してください。
インストール
pip install user-permission
依存パッケージはありません (Rust 拡張に同梱)。Python 3.9 以降の abi3 wheel を公開しています。
ソースからビルドする場合:
uv run maturin develop # 開発用に現在の venv に組み込む
uv run maturin build --release # リリース wheel をビルド
使い方
初期化
import asyncio
from user_permission import Database
async def main():
# 初回実行時にシークレットキーを自動生成(以降はファイルから読み込み)
async with Database("app.db", secret="secret.key") as db:
user = await db.users.create("alice", "password123")
group = await db.groups.create("admins")
asyncio.run(main())
ユーザー管理
user = await db.users.create("alice", "password123", display_name="Alice")
user = await db.users.get_by_id(1)
user = await db.users.get_by_username("alice")
users = await db.users.list_all()
await db.users.update(user.id, password="new_password")
await db.users.update(user.id, display_name="Alice Smith")
await db.users.update(user.id, is_active=False)
await db.users.delete(user.id)
認証・トークン
from datetime import timedelta
token = await db.login("alice", "password123")
token = await db.login(
"alice", "password123", expires_delta=timedelta(hours=24)
)
# トークンを検証してユーザーを解決(無効・期限切れは None)
user = await db.verify_token_and_get_user(token)
print(user.id) # ユーザーID
print(user.username) # ユーザー名
print(await db.users.is_admin(user.id)) # bool
グループ管理
group = await db.groups.create("admins", description="Administrator group")
group = await db.groups.get_by_id(1)
group = await db.groups.get_by_name("admins")
groups = await db.groups.list_all()
await db.groups.update(group.id, description="Updated description")
await db.groups.delete(group.id)
グループメンバー管理
await db.groups.add_user(group.id, user.id)
await db.groups.remove_user(group.id, user.id)
members = await db.groups.get_members(group.id)
groups = await db.groups.get_user_groups(user.id)
サーバー起動
import asyncio
from user_permission import serve
asyncio.run(serve(host="0.0.0.0", port=8001, prefix="/api", webui=True))
CLI からも起動できます。
user-permission serve --host 0.0.0.0 --port 8001 --prefix /api --webui
| オプション | デフォルト | 説明 |
|---|---|---|
--host |
127.0.0.1 |
バインドアドレス |
--port |
8000 |
バインドポート |
--database |
user_permission.db |
SQLiteデータベースのパス |
--secret |
secret.key |
シークレットキーファイルのパス |
--prefix |
(なし) | APIルートプレフィックス(例: /api) |
--webui |
無効 | Web管理画面を有効化 |
--webui-prefix |
/ui |
管理画面のURLプレフィックス |
リレー(中継)
Database に URL を渡すと、ローカル SQLite と中央サーバーを同じインターフェースで切り替えられます。
from user_permission import Database
# ファイルパス → ローカル SQLite
db = Database("app.db", secret="secret.key")
# URL → リモートサーバーへ HTTP 中継
async with Database("http://localhost:8001") as db:
token = await db.login("alice", "password123")
users = await db.users.list_all()
db.login(...) で取得したトークンは Database が内部に保持し、以降のリクエストの Authorization: Bearer に自動付与されます。
推奨: backend を意識しない実装。 認証(db.login / db.login_service)、トークン検証(db.verify_token_and_get_user)、ユーザー・グループ操作はすべてローカル / リレーで同一の呼び出しで動作します。接続先 URL(またはファイルパス)を切り替えるだけで、アプリ側のコードを変えずにローカル運用と中央サーバー運用を行き来できます。
# どちらの backend でも同じコードが動く
async def authenticate(db: Database, username: str, password: str):
# login 失敗時は None、verify_token_and_get_user は None を渡すと None を返す
token = await db.login(username, password)
return await db.verify_token_and_get_user(token)
サービスクライアントの管理操作だけは例外でローカル専用です(後述)。
サービスクライアント認証(client-credentials)
サービス間連携向けに、平文パスワードを持たずに読み取り専用のスコープ付きトークンを発行できます。
クライアントには users:read / groups:read のスコープのみ付与でき、書き込みや管理操作はできません。
from user_permission import Database, SCOPE_USERS_READ
# 管理側(ローカル)でサービスクライアントを発行。secret は発行時のみ取得可能。
async with Database("app.db", secret="secret.key") as db:
client, secret = await db.service_clients.create("reader", [SCOPE_USERS_READ])
# リレー側はサービストークンでログインし、スコープ内のみ読み取れる。
async with Database("http://localhost:8001") as relay:
await relay.login_service(client.client_id, secret)
users = await relay.users.list_all() # users:read があるので OK
注意: 管理操作はローカル backend 専用です。
service_clients.create/list/get_by_client_id/delete/rotate_secretはリレー(URL)backend で呼ぶとエラーになります(サービスクライアントの発行・管理は中央サーバー側で行う設計のため)。一方、サービス認証(db.login_service(...))はローカル / リレーのどちらでも動作します。
バックエンド非依存のユーティリティ
ローカル / リレーのどちらでも同じ呼び出しで動作します。
# トークンを検証してユーザーを解決(無効・期限切れ・サービストークンは None)
user = await db.verify_token_and_get_user(token)
# 管理者が不在なら作成して昇格(リレーでは no-op)
await db.bootstrap_admin_if_needed("admin", "password123")
REST API・管理者ロール・スキーマ
REST エンドポイント仕様、groups.is_admin による管理者ロールの扱い、データベーススキーマは
Rust リポジトリの README を参照してください。
開発
# Python wheel をビルドして現在の venv に組み込む
uv run maturin develop
# Python 統合テスト
uv run --with pytest --with pytest-asyncio pytest tests/python
# リリース wheel をビルド
uv run maturin build --release
リリース
pyproject.toml のバージョンを更新し、v で始まる Git タグを push すると GitHub Actions が
全プラットフォームの wheel をビルドして PyPI に公開します (詳細は .github/workflows/release.yml)。
ライセンス
MIT OR Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
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 user_permission-0.7.0.tar.gz.
File metadata
- Download URL: user_permission-0.7.0.tar.gz
- Upload date:
- Size: 42.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76ed2b1729f958890b89b038725e91a64a6c3388b93f37dcec356631f73ce6c8
|
|
| MD5 |
33adf9e64704cf7d8878055b5ca26bf0
|
|
| BLAKE2b-256 |
745dc102e73e85f2f3e66ada37bdfc9f22aa8edaaec9b3e384122dd185217871
|
Provenance
The following attestation bundles were made for user_permission-0.7.0.tar.gz:
Publisher:
release.yml on Mokuichi147/user-permission-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.7.0.tar.gz -
Subject digest:
76ed2b1729f958890b89b038725e91a64a6c3388b93f37dcec356631f73ce6c8 - Sigstore transparency entry: 2204693496
- Sigstore integration time:
-
Permalink:
Mokuichi147/user-permission-py@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.7.0-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: user_permission-0.7.0-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 4.4 MB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67ac271308883ae96fe378cd81ed0ffa31fd991f8fbdad7402a9c1dbb9923794
|
|
| MD5 |
24f81870af5e7273e7b71cfb5731403b
|
|
| BLAKE2b-256 |
e9598128b74fb141416af85f9b90c6ce1c0d92065f2354bd03d56e4faf6ed3fa
|
Provenance
The following attestation bundles were made for user_permission-0.7.0-cp39-abi3-win_amd64.whl:
Publisher:
release.yml on Mokuichi147/user-permission-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.7.0-cp39-abi3-win_amd64.whl -
Subject digest:
67ac271308883ae96fe378cd81ed0ffa31fd991f8fbdad7402a9c1dbb9923794 - Sigstore transparency entry: 2204693504
- Sigstore integration time:
-
Permalink:
Mokuichi147/user-permission-py@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.7.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: user_permission-0.7.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 4.2 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c1c981dc83356a6a96453bcf344347c74a6812fdc0e5f94b068ad37dc11a25e3
|
|
| MD5 |
66666ac07a674bc75f21c5f138bfc669
|
|
| BLAKE2b-256 |
6264331c655f71b93ff6bb18d32ee4f61a824cdf74a26edca1b83b6e81f8e02a
|
Provenance
The following attestation bundles were made for user_permission-0.7.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on Mokuichi147/user-permission-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.7.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
c1c981dc83356a6a96453bcf344347c74a6812fdc0e5f94b068ad37dc11a25e3 - Sigstore transparency entry: 2204693501
- Sigstore integration time:
-
Permalink:
Mokuichi147/user-permission-py@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.7.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: user_permission-0.7.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 3.9 MB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ffa97998bb57806d13fd487b8bd7070924281615989247f5cf7b5f10c16dc21
|
|
| MD5 |
a05c488655009399bbcbc8db591f6850
|
|
| BLAKE2b-256 |
32903a1bb6f0db07d85ad1add7b315bcf554d9b4d172653c2b5ff18c2fa61567
|
Provenance
The following attestation bundles were made for user_permission-0.7.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on Mokuichi147/user-permission-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.7.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
5ffa97998bb57806d13fd487b8bd7070924281615989247f5cf7b5f10c16dc21 - Sigstore transparency entry: 2204693497
- Sigstore integration time:
-
Permalink:
Mokuichi147/user-permission-py@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.7.0-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: user_permission-0.7.0-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 3.8 MB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a0cfc16a564311af390bf8cbdb42f45c7abafed6558c00aaa077c727dfa709d3
|
|
| MD5 |
f2dd3ff42d62301b1890e9dadb0ccf53
|
|
| BLAKE2b-256 |
80f789c993057efd131a79da7811dc9cc2ac0a2811a659c6d4185cac35839f6b
|
Provenance
The following attestation bundles were made for user_permission-0.7.0-cp39-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on Mokuichi147/user-permission-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.7.0-cp39-abi3-macosx_11_0_arm64.whl -
Subject digest:
a0cfc16a564311af390bf8cbdb42f45c7abafed6558c00aaa077c727dfa709d3 - Sigstore transparency entry: 2204693499
- Sigstore integration time:
-
Permalink:
Mokuichi147/user-permission-py@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file user_permission-0.7.0-cp39-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: user_permission-0.7.0-cp39-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 4.1 MB
- Tags: CPython 3.9+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ab9950483013e61d9f4ff45a0c4715390bcf932e515ea960185a1062bc25c7c
|
|
| MD5 |
8947f69a92aa8ee13241d2f99c573375
|
|
| BLAKE2b-256 |
b5be811d4b63fcdf906785cd07366ea370c48a0b4d545e747a962f4b03d3eddd
|
Provenance
The following attestation bundles were made for user_permission-0.7.0-cp39-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on Mokuichi147/user-permission-py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
user_permission-0.7.0-cp39-abi3-macosx_10_12_x86_64.whl -
Subject digest:
1ab9950483013e61d9f4ff45a0c4715390bcf932e515ea960185a1062bc25c7c - Sigstore transparency entry: 2204693505
- Sigstore integration time:
-
Permalink:
Mokuichi147/user-permission-py@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Branch / Tag:
refs/tags/v0.7.0 - Owner: https://github.com/Mokuichi147
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@18bd2613cea888a0fe82d11a3fdceb22043d72e5 -
Trigger Event:
push
-
Statement type: