kx-auth-cli 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kx_auth_cli/__init__.py +11 -0
- kx_auth_cli/assert_cmd.py +278 -0
- kx_auth_cli/atomic.py +54 -0
- kx_auth_cli/cache.py +66 -0
- kx_auth_cli/cli.py +103 -0
- kx_auth_cli/discovery.py +261 -0
- kx_auth_cli/envelope.py +145 -0
- kx_auth_cli/exchange.py +212 -0
- kx_auth_cli/introspect.py +162 -0
- kx_auth_cli/login.py +153 -0
- kx_auth_cli/qbridge.py +54 -0
- kx_auth_cli/rbac.py +759 -0
- kx_auth_cli-0.5.0.dist-info/METADATA +116 -0
- kx_auth_cli-0.5.0.dist-info/RECORD +16 -0
- kx_auth_cli-0.5.0.dist-info/WHEEL +4 -0
- kx_auth_cli-0.5.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: kx-auth-cli
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: kx auth and kx rbac — client-side OAuth/identity assertion plus atomic policy administration for the kx.auth and kx.rbac q modules (no fastmcp).
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Python: <3.14,>=3.10
|
|
7
|
+
Requires-Dist: httpx
|
|
8
|
+
Requires-Dist: kx-auth-core<0.6,>=0.5.0b1
|
|
9
|
+
Provides-Extra: qipc
|
|
10
|
+
Requires-Dist: pykx>=4.0.0.b4; extra == 'qipc'
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# kx-auth-cli — the `kx auth` CLI
|
|
14
|
+
|
|
15
|
+
The client-side auth CLI for kdb+ identity assertion, and the OAuth-aware half of the
|
|
16
|
+
[`kx.auth`](../../modules/kx/auth/) story. The q module does no token parsing and no crypto, on purpose,
|
|
17
|
+
so acquiring a bearer, exchanging it for a backend-scoped one, and projecting it into a principal all
|
|
18
|
+
happen out here. `assert` binds the result onto a kdb+ process over qIPC.
|
|
19
|
+
|
|
20
|
+
It ships the `kx` console script with `auth` and `rbac` command groups.
|
|
21
|
+
|
|
22
|
+
| Command | What it does | Needs |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| `auth login` | Acquire a bearer: RFC 9728 discovery, then RFC 8628 device code. | a resource server |
|
|
25
|
+
| `auth exchange` | Swap any subject token for a backend-scoped one (RFC 8693). | a token endpoint |
|
|
26
|
+
| `auth assert` | Project a principal; with `--connect`, run the live `.kx.auth.bind` handshake. | a q host running `kx.auth` |
|
|
27
|
+
| `auth introspect` | Validate a bearer: issuer, audience, signature, expiry, scopes. | a JWKS URI or public key |
|
|
28
|
+
| `rbac …` | Inspect, test and atomically administer policy. | a q host running `kx.rbac` |
|
|
29
|
+
|
|
30
|
+
**Full command reference: [KX_AUTH_CLI.md](../../docs/KX_AUTH_CLI.md).** Flags, output envelopes,
|
|
31
|
+
credential precedence, the gateway route table and the environment variables all live there.
|
|
32
|
+
|
|
33
|
+
It runs where the client runs, not where kdb+ runs, so it depends on the lean `kx-auth-core` plus
|
|
34
|
+
`httpx` and never on `fastmcp`.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv tool install kx-auth-cli # or: pipx install kx-auth-cli
|
|
40
|
+
kx auth --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Add the `qipc` extra for the live `assert --connect` handshake, which needs PyKX:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
uv tool install 'kx-auth-cli[qipc]'
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Run without installing (`uvx`)
|
|
50
|
+
|
|
51
|
+
The `kx` console script is the whole entry point, and `uvx` runs it from the published wheel in an
|
|
52
|
+
ephemeral environment:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uvx --from kx-auth-cli kx auth --help
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`--from kx-auth-cli` names the package that owns the `kx` command, since `uvx` can't infer it from the
|
|
59
|
+
executable name. Add the `qipc` extra the same way: `--from 'kx-auth-cli[qipc]'`. To pin a version, use
|
|
60
|
+
`--from kx-auth-cli==<X.Y.Z>`. The CLI shares its version number with the q modules' releases.
|
|
61
|
+
|
|
62
|
+
## Exit codes
|
|
63
|
+
|
|
64
|
+
Stable across every subcommand. Branch on the code, not the text.
|
|
65
|
+
|
|
66
|
+
| Code | Meaning |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `0` | ok, allowed |
|
|
69
|
+
| `1` | error |
|
|
70
|
+
| `2` | usage |
|
|
71
|
+
| `3` | auth-required |
|
|
72
|
+
| `4` | denied |
|
|
73
|
+
|
|
74
|
+
Every subcommand supports `--json`, which emits exactly one envelope: `{"status": …, "result": …}` on
|
|
75
|
+
success, `{"status": …, "reason": …}` on failure — and a `denied` decision or a tripped `--fail-on`
|
|
76
|
+
carries `result` too. Every command's payload lives under `result`; all five share one emitter
|
|
77
|
+
(`kx_auth_cli/envelope.py`), so none can drift from the shape or the exit table.
|
|
78
|
+
|
|
79
|
+
Which input earns which code is documented per command in
|
|
80
|
+
[`docs/KX_AUTH_CLI.md`](../../docs/KX_AUTH_CLI.md) — as a rule of thumb, a malformed *document* (a
|
|
81
|
+
`--principal` file, a server's response) is an error (`1`), while a malformed *flag value* (`--ctx`, an
|
|
82
|
+
unknown `--strategy`) is usage (`2`).
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv pip install -e '.[qipc]' --group dev
|
|
88
|
+
pytest
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The suite is hermetic: no live IdP, no Keycloak, no kdb+. `login`'s tests stand up an in-process mock
|
|
92
|
+
authorization server, and `assert --connect`'s inject a fake `pykx`. Tokens are minted with PyJWT while
|
|
93
|
+
`kx-auth-core` verifies with joserfc, which is deliberate cross-library coverage.
|
|
94
|
+
|
|
95
|
+
Because it fakes `pykx`, **no test here proves the qIPC handshake works against real kdb+.** That is
|
|
96
|
+
[`demos/local-assertion/cli-check.sh`](../../demos/local-assertion/cli-check.sh), which drives a live
|
|
97
|
+
demo host with this CLI. Install the `[qipc]` extra and `bash demos/local-assertion/run.sh` picks it up.
|
|
98
|
+
Run both when you touch `assert`.
|
|
99
|
+
|
|
100
|
+
### The fastmcp-free invariant
|
|
101
|
+
|
|
102
|
+
This CLI ships light: `kx-auth-core` and `httpx` only, and it must never import `fastmcp`. Three things
|
|
103
|
+
hold the line.
|
|
104
|
+
|
|
105
|
+
- `introspect`'s verifier is the shared `kx_auth_core.verify_token`, so bearer validation has one
|
|
106
|
+
implementation rather than a client-side copy to drift.
|
|
107
|
+
- `login`'s discovery, device-code and cache machinery is CLI-local rather than in `kx-auth-core`. A
|
|
108
|
+
server never logs in, and the cache is a client concern.
|
|
109
|
+
- PyKX is imported lazily, only on the `--connect` path, and ships in the `qipc` extra.
|
|
110
|
+
|
|
111
|
+
Pinned by `test_assert_cmd_import_is_fastmcp_free`, which fails if importing the command pulls
|
|
112
|
+
`fastmcp` into the process.
|
|
113
|
+
|
|
114
|
+
`--json` stdout is exactly one envelope, including on the PyKX path. PyKX's Community banner is
|
|
115
|
+
suppressed during the lazy import, so consumers should treat any surrounding output as a contract
|
|
116
|
+
violation.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
kx_auth_cli/__init__.py,sha256=BMgpl-G7qD9t1S9flZUf-WSDaGJJRCFgPZOROd2kfC4,752
|
|
2
|
+
kx_auth_cli/assert_cmd.py,sha256=lqDy4SsPOhCMbQthg7_TTq0Xd8niRSOmhlNk1XWZEfI,13607
|
|
3
|
+
kx_auth_cli/atomic.py,sha256=gKuqfCHoNhUjfUqZNQJrF5UTkAjQUE7hAZ5sD6v2s7g,2435
|
|
4
|
+
kx_auth_cli/cache.py,sha256=SAYDizo3IRTJekumPknV1YNU65ASak0q5060YoL1pfw,2777
|
|
5
|
+
kx_auth_cli/cli.py,sha256=TwVfEjudSu5j-90mzTK-Hw6qAfDfNeYoPzEcAgppfBI,4041
|
|
6
|
+
kx_auth_cli/discovery.py,sha256=BAuPpKvNs6NkzvZRptrLEgVlz_OHPht4ahbBAsABXAk,11171
|
|
7
|
+
kx_auth_cli/envelope.py,sha256=rB2k18SGWzgZDcJVv8ejNpb7EFpID5Q4gvlfW0afvew,5684
|
|
8
|
+
kx_auth_cli/exchange.py,sha256=3-dFpbDpzwaonljkK4di5kyxBCvwwAs7iin_6jzi3-0,10389
|
|
9
|
+
kx_auth_cli/introspect.py,sha256=7kW5GfTcSfAyBN1rFz97zDRJmqfMoa9nuM47L-P3HYA,7364
|
|
10
|
+
kx_auth_cli/login.py,sha256=w0RV6Npo-EHcqblKUaT6qAlbwNjubUWdsllGwSbJMfM,6745
|
|
11
|
+
kx_auth_cli/qbridge.py,sha256=W-x6xKItaMgOmx3pxReVGU5XQVoOSFZtjx4pkeU5INM,1923
|
|
12
|
+
kx_auth_cli/rbac.py,sha256=R05bhd2Kp7u_HAcytvHuWJzkpCG_VIa1v9TyCMqzPz0,34802
|
|
13
|
+
kx_auth_cli-0.5.0.dist-info/METADATA,sha256=m7Fvhfw-sGiVGhYVhTxGDxPO_hq-tuEbZinKo9gkd-s,5082
|
|
14
|
+
kx_auth_cli-0.5.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
15
|
+
kx_auth_cli-0.5.0.dist-info/entry_points.txt,sha256=8Ypxn3t-7iYbDMh6TFppWMyxwVK4Yl5ANGtf2U4pMRQ,44
|
|
16
|
+
kx_auth_cli-0.5.0.dist-info/RECORD,,
|