mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-05-30 01:35:14 +02:00
Three threads, all reinforcing the contract's system-level vs.
workspace-association distinction.
WS Mux service routing
- tg-show-flows (and any workspace-level service over the WS) was
failing with "unknown service" because the post-refactor Mux
unconditionally looked up flow-service:<kind>. Now branches on
the envelope's flow field: with flow → flow-service:<kind>;
without flow → <kind>:<op> from the inner body; with bare op
lookup for service=iam. Resource and parameters come from the
matched op's own extractors — same path the HTTP endpoints take.
Optional workspace on system-level user/key ops
- list-users returns the deployment-wide list when no workspace is
supplied, filters when one is. get-user, update-user,
disable-user, enable-user, delete-user, reset-password,
create-api-key, list-api-keys, revoke-api-key all treat workspace
as an optional integrity check rather than a required argument.
- create-user keeps workspace required — there it's the new user's
home-workspace binding, a parameter rather than an address.
- API keys reclassified as SYSTEM-level resources. By the same
reasoning that makes users system-level, an API key is a
credential record on a deployment-wide registry; the workspace it
authenticates to is a property, not a containment.
Self-service surface
- whoami: returns the caller's own user record. AUTHENTICATED-only;
no users:read capability required. Foundation for UI affordances
that depend on the caller's permissions.
- bootstrap-status: POST /api/v1/auth/bootstrap-status, PUBLIC,
side-effect-free. Returns {bootstrap_available: bool} so a
first-run UI can decide whether to render setup without consuming
the bootstrap op.
- Gateway now injects actor=identity.handle on every authenticated
forward to iam-svc (IamEndpoint and WS Mux iam path), overwriting
any caller-supplied value. Underpins whoami, audit logging, and
future regime-side decisions that need actor identity.
- tg-whoami and tg-update-user CLIs.
Spec polish
- iam-contract.md: actor-injection rule documented; whoami /
bootstrap-status added to operations list; permission-scope
framing tightened (workspace scope is a property of the grant,
not the user or role).
- iam.md: self-service section; gateway flow gains the actor-
injection step; role section reframed so iam-svc constraints
don't leak into contract-level prose.
- iam-protocol.md: ops table updated for whoami, bootstrap-status,
optional-workspace pattern; bootstrap_available added to the
IamResponse listing.
52 lines
1.3 KiB
Python
52 lines
1.3 KiB
Python
"""
|
|
Show the authenticated caller's own user record.
|
|
"""
|
|
|
|
import argparse
|
|
|
|
import tabulate
|
|
|
|
from ._iam import DEFAULT_URL, DEFAULT_TOKEN, call_iam, run_main
|
|
|
|
|
|
def do_whoami(args):
|
|
resp = call_iam(args.api_url, args.token, {"operation": "whoami"})
|
|
user = resp.get("user")
|
|
if not user:
|
|
print("(no user record returned)")
|
|
return
|
|
|
|
rows = [
|
|
["id", user.get("id", "")],
|
|
["username", user.get("username", "")],
|
|
["name", user.get("name", "")],
|
|
["email", user.get("email", "")],
|
|
["workspace", user.get("workspace", "")],
|
|
["roles", ", ".join(user.get("roles", []))],
|
|
["enabled", "yes" if user.get("enabled") else "no"],
|
|
[
|
|
"must change password",
|
|
"yes" if user.get("must_change_password") else "no",
|
|
],
|
|
["created", user.get("created", "")],
|
|
]
|
|
print(tabulate.tabulate(rows, tablefmt="plain"))
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
prog="tg-whoami", description=__doc__,
|
|
)
|
|
parser.add_argument(
|
|
"-u", "--api-url", default=DEFAULT_URL,
|
|
help=f"API URL (default: {DEFAULT_URL})",
|
|
)
|
|
parser.add_argument(
|
|
"-t", "--token", default=DEFAULT_TOKEN,
|
|
help="Auth token (default: $TRUSTGRAPH_TOKEN)",
|
|
)
|
|
run_main(do_whoami, parser)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|