generated from coulomb/repo-seed
feat(local-identity): Stage 3 — minimal native OIDC provider (NK-WP-0002-T03)
Add local-identity serve command: a minimal Authorization Code flow OIDC server backed by file-store users. Implemented natively with no heavy OIDC library — only stdlib http.server and the cryptography package. New modules: keys.py RSA-2048 signing key generation + JWKS helpers tls.py Self-signed TLS certificate (localhost/127.0.0.1 SANs) jwt_utils.py RS256 JWT creation and verification serve.py OIDCHandler + make_handler() factory + run_server() Endpoints: /.well-known/openid-configuration, /jwks, /auth, /token, /userinfo. Server binds to 127.0.0.1 only; tokens carry iss: local-identity which production Keycloak rejects by design. 104 tests passing (16 new for Stage 3). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,7 @@ Commands:
|
||||
export [<username>] Export a single user as Keycloak JSON.
|
||||
export --all [--realm R] Bulk partial-import body (primary users only).
|
||||
Add --include-test to include generated users.
|
||||
serve [--port P] [--ttl T] Start the minimal OIDC server on 127.0.0.1.
|
||||
|
||||
Environment:
|
||||
LOCAL_IDENTITY_HOME Override the store directory (default: ~/.local-identity).
|
||||
@@ -23,6 +24,7 @@ import sys
|
||||
from .gecos import current_username, get_gecos_fullname
|
||||
from .user import UserRecord, make_test_user
|
||||
from . import export as export_mod
|
||||
from . import serve as serve_mod
|
||||
from . import store
|
||||
|
||||
|
||||
@@ -133,6 +135,10 @@ def cmd_show(args: argparse.Namespace) -> None:
|
||||
print(user.to_yaml(), end="")
|
||||
|
||||
|
||||
def cmd_serve(args: argparse.Namespace) -> None:
|
||||
serve_mod.run_server(port=args.port, token_ttl=args.ttl)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="local-identity",
|
||||
@@ -196,6 +202,20 @@ def main() -> None:
|
||||
p_show.add_argument("username", help="Username to display")
|
||||
p_show.set_defaults(func=cmd_show)
|
||||
|
||||
p_serve = sub.add_parser(
|
||||
"serve",
|
||||
help="Start the minimal OIDC server (127.0.0.1 only)",
|
||||
)
|
||||
p_serve.add_argument(
|
||||
"--port", type=int, default=8443,
|
||||
help="Port to listen on (default: 8443)",
|
||||
)
|
||||
p_serve.add_argument(
|
||||
"--ttl", type=int, default=3600,
|
||||
help="Token TTL in seconds (default: 3600)",
|
||||
)
|
||||
p_serve.set_defaults(func=cmd_serve)
|
||||
|
||||
args = parser.parse_args()
|
||||
args.func(args)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user