aac-cli 0.2.9__tar.gz → 0.2.10__tar.gz
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.
- {aac_cli-0.2.9/aac_cli.egg-info → aac_cli-0.2.10}/PKG-INFO +95 -7
- {aac_cli-0.2.9 → aac_cli-0.2.10}/README.md +94 -6
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/__init__.py +1 -1
- aac_cli-0.2.10/aac_cli/__main__.py +13 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/aeg_cli.py +5 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/agent_cli.py +15 -2
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/agent_health.py +21 -4
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/cli.py +230 -54
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/config.py +145 -35
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/init_cli.py +3 -3
- aac_cli-0.2.10/aac_cli/interrupts.py +48 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/profiles.py +114 -59
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/reference.py +13 -4
- {aac_cli-0.2.9 → aac_cli-0.2.10/aac_cli.egg-info}/PKG-INFO +95 -7
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli.egg-info/SOURCES.txt +1 -0
- aac_cli-0.2.10/launchers/aac +36 -0
- aac_cli-0.2.10/launchers/aeg +33 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/pyproject.toml +2 -2
- aac_cli-0.2.9/aac_cli/__main__.py +0 -6
- aac_cli-0.2.9/launchers/aac +0 -32
- aac_cli-0.2.9/launchers/aeg +0 -29
- {aac_cli-0.2.9 → aac_cli-0.2.10}/LICENSE +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/MANIFEST.in +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/NOTICE +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/THIRD_PARTY_NOTICES.md +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/__init__.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/cli.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/data/action-taken-v1.json +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/data/predicates-v1.json +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/data/renderer-source.json +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/from_sidecar.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/inputs.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/model.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/narrative.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/provenance.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/schemas.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/temporal.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/theme.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/timeline_source.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/_aeg/visualizer.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/admin_key_pem.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/aeg_list.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/agent_config.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/agent_layout.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/agent_record.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/api_key_rotation_state.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/chain_list.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/config_render.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/dev_material.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/idp_recovery.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/material_cases.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/registration_state.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/secure_files.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/sso_login.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/supplied_material.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli/trace_query.py +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli.egg-info/dependency_links.txt +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli.egg-info/requires.txt +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/aac_cli.egg-info/top_level.txt +0 -0
- {aac_cli-0.2.9 → aac_cli-0.2.10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aac-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.10
|
|
4
4
|
Summary: The aac platform CLI — headless operator interface to the AAC control plane (tenant registration, chain audit).
|
|
5
5
|
Author: Agent Authority Cloud Project
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -741,6 +741,7 @@ aac profile show stage --output table # stored and effective values,
|
|
|
741
741
|
aac profile create prod --admin-url https://aac-admin.example.com \
|
|
742
742
|
--data-plane-url https://aac-data.example.com
|
|
743
743
|
aac profile update main # edit the built-in baseline
|
|
744
|
+
aac profile update stage --unbind # clear the local tenant association
|
|
744
745
|
aac profile delete prod # local only; never touches the server
|
|
745
746
|
```
|
|
746
747
|
|
|
@@ -757,6 +758,41 @@ stored value.
|
|
|
757
758
|
for it; only `aac tenant register`, `aac init` and `aac sso login` write it.
|
|
758
759
|
It is your organisation's identifier in the federation, allocated by AAC at
|
|
759
760
|
registration in the form `tnt-<uuid>`, and it never changes.
|
|
761
|
+
A binding makes that tenant the profile's stored default; it does not grant
|
|
762
|
+
membership or configure an identity provider. Successful sign-in to an existing
|
|
763
|
+
tenant binds the profile; registration binds a newly created tenant.
|
|
764
|
+
|
|
765
|
+
A stale tenant binding affects only that profile. `aac profile list` and
|
|
766
|
+
`aac profile show` mark invalid bindings without printing the invalid values;
|
|
767
|
+
other profiles remain usable. Operational commands reject a selected invalid
|
|
768
|
+
profile with exit 3, even if a tenant flag or environment override is supplied.
|
|
769
|
+
File syntax, profile-name and size limits still apply to the entire file.
|
|
770
|
+
|
|
771
|
+
Use `aac profile update NAME --unbind` to remove the local `tenant_id` and its
|
|
772
|
+
saved hosted-domain metadata. Endpoints, other settings, credentials and the
|
|
773
|
+
server-side tenant are preserved. The flag works without prompts, may accompany
|
|
774
|
+
endpoint flags, and also works on `main` or an already-unbound profile. It
|
|
775
|
+
refuses profiles with unresolved registration or API-key rotation state;
|
|
776
|
+
finish that recovery first. Then bind the profile through registration or
|
|
777
|
+
successful sign-in. Endpoint-only updates and confirmed profile deletion also
|
|
778
|
+
work on stale profiles; reads never rewrite the config file.
|
|
779
|
+
|
|
780
|
+
For an existing tenant, the repair sequence is:
|
|
781
|
+
|
|
782
|
+
```bash
|
|
783
|
+
aac profile update stage --unbind
|
|
784
|
+
# Bind profile stage to the correct existing tenant:
|
|
785
|
+
aac sso login --profile stage --tenant-id '<TENANT_ID>'
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
**`aac sso login --profile stage --tenant-id '<TENANT_ID>'` binds profile
|
|
789
|
+
`stage` to that tenant.** Although the verb is `login`, successful authentication
|
|
790
|
+
also saves the tenant association; there is no separate `--bind` flag. Replace
|
|
791
|
+
`<TENANT_ID>` with the intended tenant's canonical ID. An endpoint correction
|
|
792
|
+
or expired session normally does not need
|
|
793
|
+
unbinding. Unbinding is local and does not log out, revoke access, or change
|
|
794
|
+
existing agent records. See the [profile repair guide](https://docs.cascadeauth.com/cli/guide/#repair-a-stale-profile-binding)
|
|
795
|
+
for the exact config fields removed and recovery constraints.
|
|
760
796
|
|
|
761
797
|
`AAC_CLI_HOME` relocates the whole `~/.aac` tree. Use it for a throwaway
|
|
762
798
|
test home, or to keep separate accounts hard-walled from each other:
|
|
@@ -774,13 +810,39 @@ Two credential files can coexist under `~/.aac/credentials/`:
|
|
|
774
810
|
(`aac chain`, `aac trust-anchor`) present it. Only a hash of it exists
|
|
775
811
|
on the server, so a lost key is replaced, never recovered.
|
|
776
812
|
* `<tenant-id>.session` holds the short-lived session that `aac sso login`
|
|
777
|
-
creates.
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
813
|
+
creates. Authenticated administration commands use it automatically;
|
|
814
|
+
public reads such as `aac sso describe` do not use credentials.
|
|
815
|
+
Sessions have no refresh token. You can sign in again before expiry to
|
|
816
|
+
replace the cached session; after expiry, commands that need it ask you
|
|
817
|
+
to sign in again.
|
|
781
818
|
|
|
782
819
|
## Signing in
|
|
783
820
|
|
|
821
|
+
Inspect the available sign-in connections before starting a login:
|
|
822
|
+
|
|
823
|
+
```bash
|
|
824
|
+
aac sso describe --profile stage # shared/platform candidates
|
|
825
|
+
aac sso describe --profile stage --tenant-id '<TENANT_ID>' # tenant plus shared candidates
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
`sso describe` reads public metadata from the profile's admin endpoint and
|
|
829
|
+
prints the complete descriptor as JSON on stdout. No credentials or prior
|
|
830
|
+
sign-in are required, and it does not bind a profile or change cached credentials.
|
|
831
|
+
The output includes `connections`, `count`, and, for the tenant route,
|
|
832
|
+
`tenant_id`; connection fields describe issuers, client IDs and available flow
|
|
833
|
+
endpoints. An empty connection list is a successful read.
|
|
834
|
+
|
|
835
|
+
Only an explicit `--tenant-id` selects the tenant descriptor. Omitting it
|
|
836
|
+
always reads shared/platform candidates, even when the profile or the
|
|
837
|
+
`AAC_TENANT_ID` environment variable supplies a tenant. Replace `<TENANT_ID>`
|
|
838
|
+
with the intended tenant's canonical ID. The CLI still checks your local
|
|
839
|
+
configuration and selected profile. If it reports an invalid stored tenant
|
|
840
|
+
binding, clear it with `aac profile update stage --unbind`, then retry.
|
|
841
|
+
Output is JSON only (`--output json` is optional); errors go to stderr.
|
|
842
|
+
See the [command reference](https://docs.cascadeauth.com/cli/reference/aac-sso-describe/).
|
|
843
|
+
|
|
844
|
+
Then sign in using the connection you need:
|
|
845
|
+
|
|
784
846
|
```bash
|
|
785
847
|
aac sso login --profile stage --idp github # developer tenant: GitHub or Google
|
|
786
848
|
aac sso login --profile prod \
|
|
@@ -798,6 +860,15 @@ enterprise tenant signs in through its Microsoft Entra ID connection, named
|
|
|
798
860
|
by the connection's exact URL with `--idp-url`; when several connections
|
|
799
861
|
are registered, the error message lists the exact commands to choose one.
|
|
800
862
|
|
|
863
|
+
Sessions last **4 hours by default**. Your administrator may configure a
|
|
864
|
+
different lifetime for the deployment or connection. You can run
|
|
865
|
+
`aac sso login` again before expiry: successful authentication replaces the
|
|
866
|
+
cached session with a new one whose lifetime starts at that login. For example,
|
|
867
|
+
with the four-hour default, signing in at 09:00 gives an expiry of 13:00;
|
|
868
|
+
signing in successfully again at 12:00 gives the new session an expiry of 16:00.
|
|
869
|
+
Use `aac sso whoami --profile NAME --output table` to check the current
|
|
870
|
+
expiration. If the session expires, sign in again; no refresh token is issued.
|
|
871
|
+
|
|
801
872
|
Sign-in uses the device flow by default, so the browser can be on another
|
|
802
873
|
machine and headless hosts work. Google connections use a loopback flow
|
|
803
874
|
instead, because Google's device flow is scope-restricted; `--flow`
|
|
@@ -814,11 +885,16 @@ server-returned domain. Existing agents expose read-only identities through
|
|
|
814
885
|
or `--field workload-spiffe-id`. A successful scalar is one unquoted line;
|
|
815
886
|
an unavailable value or unhealthy agent fails with empty stdout. `--field`
|
|
816
887
|
cannot be combined with explicit `--output`, or with agent `--remote`.
|
|
888
|
+
Scalar profile inspection rejects an invalid stored binding. Structured
|
|
889
|
+
inspection remains available and reports invalid effective IDs as `null` with
|
|
890
|
+
an `error`; invalid list bindings carry `binding_error`, and show bindings carry
|
|
891
|
+
`binding.error`. Their invalid stored tenant IDs are redacted as `null`.
|
|
817
892
|
|
|
818
893
|
Every command that reports a result prints one JSON document to standard
|
|
819
894
|
output by default, with progress notes and diagnostics on standard error,
|
|
820
|
-
so the JSON stays parseable in scripts; `--output table`
|
|
821
|
-
table instead.
|
|
895
|
+
so the JSON stays parseable in scripts; where supported, `--output table`
|
|
896
|
+
prints a readable table instead. `aac sso describe` supports JSON only.
|
|
897
|
+
The three profile writers are the exception: `aac profile
|
|
822
898
|
create`, `update` and `delete` confirm on standard error, leave standard
|
|
823
899
|
output empty and take no `--output`.
|
|
824
900
|
|
|
@@ -829,6 +905,18 @@ output empty and take no `--output`.
|
|
|
829
905
|
| `2` | Usage error: an invalid flag, value or flag combination. |
|
|
830
906
|
| `3` | A local configuration or state problem: profile, credential file, cached session or agent. |
|
|
831
907
|
| `4` | Transport failure: an endpoint could not be reached. |
|
|
908
|
+
| `130` | Interrupted by the operator (Ctrl-C). |
|
|
909
|
+
|
|
910
|
+
Ctrl-C stops `aac` and CLI-owned `aeg` without a traceback, with one concise
|
|
911
|
+
diagnostic on standard error. A remote change may already have committed;
|
|
912
|
+
follow any recovery guidance and retain pending registration or key-operation
|
|
913
|
+
state. The CLI does not roll back or automatically retry a remote change.
|
|
914
|
+
|
|
915
|
+
Walking away from sign-in retains the existing deadlines: device sign-in waits
|
|
916
|
+
for the identity provider's device-code lifetime (300 seconds if absent), then
|
|
917
|
+
exits `1` with instructions to run login again; a PKCE browser sign-in without
|
|
918
|
+
a callback gives up after 300 seconds with exit `3`. HTTP timeouts remain exit
|
|
919
|
+
`4`. These outcomes are distinct from Ctrl-C; there is no shorter patience cap.
|
|
832
920
|
|
|
833
921
|
If AAC asks you to slow down, the command shows the interval to wait. The
|
|
834
922
|
CLI never replays a change on its own; wait and rerun deliberately.
|
|
@@ -714,6 +714,7 @@ aac profile show stage --output table # stored and effective values,
|
|
|
714
714
|
aac profile create prod --admin-url https://aac-admin.example.com \
|
|
715
715
|
--data-plane-url https://aac-data.example.com
|
|
716
716
|
aac profile update main # edit the built-in baseline
|
|
717
|
+
aac profile update stage --unbind # clear the local tenant association
|
|
717
718
|
aac profile delete prod # local only; never touches the server
|
|
718
719
|
```
|
|
719
720
|
|
|
@@ -730,6 +731,41 @@ stored value.
|
|
|
730
731
|
for it; only `aac tenant register`, `aac init` and `aac sso login` write it.
|
|
731
732
|
It is your organisation's identifier in the federation, allocated by AAC at
|
|
732
733
|
registration in the form `tnt-<uuid>`, and it never changes.
|
|
734
|
+
A binding makes that tenant the profile's stored default; it does not grant
|
|
735
|
+
membership or configure an identity provider. Successful sign-in to an existing
|
|
736
|
+
tenant binds the profile; registration binds a newly created tenant.
|
|
737
|
+
|
|
738
|
+
A stale tenant binding affects only that profile. `aac profile list` and
|
|
739
|
+
`aac profile show` mark invalid bindings without printing the invalid values;
|
|
740
|
+
other profiles remain usable. Operational commands reject a selected invalid
|
|
741
|
+
profile with exit 3, even if a tenant flag or environment override is supplied.
|
|
742
|
+
File syntax, profile-name and size limits still apply to the entire file.
|
|
743
|
+
|
|
744
|
+
Use `aac profile update NAME --unbind` to remove the local `tenant_id` and its
|
|
745
|
+
saved hosted-domain metadata. Endpoints, other settings, credentials and the
|
|
746
|
+
server-side tenant are preserved. The flag works without prompts, may accompany
|
|
747
|
+
endpoint flags, and also works on `main` or an already-unbound profile. It
|
|
748
|
+
refuses profiles with unresolved registration or API-key rotation state;
|
|
749
|
+
finish that recovery first. Then bind the profile through registration or
|
|
750
|
+
successful sign-in. Endpoint-only updates and confirmed profile deletion also
|
|
751
|
+
work on stale profiles; reads never rewrite the config file.
|
|
752
|
+
|
|
753
|
+
For an existing tenant, the repair sequence is:
|
|
754
|
+
|
|
755
|
+
```bash
|
|
756
|
+
aac profile update stage --unbind
|
|
757
|
+
# Bind profile stage to the correct existing tenant:
|
|
758
|
+
aac sso login --profile stage --tenant-id '<TENANT_ID>'
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
**`aac sso login --profile stage --tenant-id '<TENANT_ID>'` binds profile
|
|
762
|
+
`stage` to that tenant.** Although the verb is `login`, successful authentication
|
|
763
|
+
also saves the tenant association; there is no separate `--bind` flag. Replace
|
|
764
|
+
`<TENANT_ID>` with the intended tenant's canonical ID. An endpoint correction
|
|
765
|
+
or expired session normally does not need
|
|
766
|
+
unbinding. Unbinding is local and does not log out, revoke access, or change
|
|
767
|
+
existing agent records. See the [profile repair guide](https://docs.cascadeauth.com/cli/guide/#repair-a-stale-profile-binding)
|
|
768
|
+
for the exact config fields removed and recovery constraints.
|
|
733
769
|
|
|
734
770
|
`AAC_CLI_HOME` relocates the whole `~/.aac` tree. Use it for a throwaway
|
|
735
771
|
test home, or to keep separate accounts hard-walled from each other:
|
|
@@ -747,13 +783,39 @@ Two credential files can coexist under `~/.aac/credentials/`:
|
|
|
747
783
|
(`aac chain`, `aac trust-anchor`) present it. Only a hash of it exists
|
|
748
784
|
on the server, so a lost key is replaced, never recovered.
|
|
749
785
|
* `<tenant-id>.session` holds the short-lived session that `aac sso login`
|
|
750
|
-
creates.
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
786
|
+
creates. Authenticated administration commands use it automatically;
|
|
787
|
+
public reads such as `aac sso describe` do not use credentials.
|
|
788
|
+
Sessions have no refresh token. You can sign in again before expiry to
|
|
789
|
+
replace the cached session; after expiry, commands that need it ask you
|
|
790
|
+
to sign in again.
|
|
754
791
|
|
|
755
792
|
## Signing in
|
|
756
793
|
|
|
794
|
+
Inspect the available sign-in connections before starting a login:
|
|
795
|
+
|
|
796
|
+
```bash
|
|
797
|
+
aac sso describe --profile stage # shared/platform candidates
|
|
798
|
+
aac sso describe --profile stage --tenant-id '<TENANT_ID>' # tenant plus shared candidates
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
`sso describe` reads public metadata from the profile's admin endpoint and
|
|
802
|
+
prints the complete descriptor as JSON on stdout. No credentials or prior
|
|
803
|
+
sign-in are required, and it does not bind a profile or change cached credentials.
|
|
804
|
+
The output includes `connections`, `count`, and, for the tenant route,
|
|
805
|
+
`tenant_id`; connection fields describe issuers, client IDs and available flow
|
|
806
|
+
endpoints. An empty connection list is a successful read.
|
|
807
|
+
|
|
808
|
+
Only an explicit `--tenant-id` selects the tenant descriptor. Omitting it
|
|
809
|
+
always reads shared/platform candidates, even when the profile or the
|
|
810
|
+
`AAC_TENANT_ID` environment variable supplies a tenant. Replace `<TENANT_ID>`
|
|
811
|
+
with the intended tenant's canonical ID. The CLI still checks your local
|
|
812
|
+
configuration and selected profile. If it reports an invalid stored tenant
|
|
813
|
+
binding, clear it with `aac profile update stage --unbind`, then retry.
|
|
814
|
+
Output is JSON only (`--output json` is optional); errors go to stderr.
|
|
815
|
+
See the [command reference](https://docs.cascadeauth.com/cli/reference/aac-sso-describe/).
|
|
816
|
+
|
|
817
|
+
Then sign in using the connection you need:
|
|
818
|
+
|
|
757
819
|
```bash
|
|
758
820
|
aac sso login --profile stage --idp github # developer tenant: GitHub or Google
|
|
759
821
|
aac sso login --profile prod \
|
|
@@ -771,6 +833,15 @@ enterprise tenant signs in through its Microsoft Entra ID connection, named
|
|
|
771
833
|
by the connection's exact URL with `--idp-url`; when several connections
|
|
772
834
|
are registered, the error message lists the exact commands to choose one.
|
|
773
835
|
|
|
836
|
+
Sessions last **4 hours by default**. Your administrator may configure a
|
|
837
|
+
different lifetime for the deployment or connection. You can run
|
|
838
|
+
`aac sso login` again before expiry: successful authentication replaces the
|
|
839
|
+
cached session with a new one whose lifetime starts at that login. For example,
|
|
840
|
+
with the four-hour default, signing in at 09:00 gives an expiry of 13:00;
|
|
841
|
+
signing in successfully again at 12:00 gives the new session an expiry of 16:00.
|
|
842
|
+
Use `aac sso whoami --profile NAME --output table` to check the current
|
|
843
|
+
expiration. If the session expires, sign in again; no refresh token is issued.
|
|
844
|
+
|
|
774
845
|
Sign-in uses the device flow by default, so the browser can be on another
|
|
775
846
|
machine and headless hosts work. Google connections use a loopback flow
|
|
776
847
|
instead, because Google's device flow is scope-restricted; `--flow`
|
|
@@ -787,11 +858,16 @@ server-returned domain. Existing agents expose read-only identities through
|
|
|
787
858
|
or `--field workload-spiffe-id`. A successful scalar is one unquoted line;
|
|
788
859
|
an unavailable value or unhealthy agent fails with empty stdout. `--field`
|
|
789
860
|
cannot be combined with explicit `--output`, or with agent `--remote`.
|
|
861
|
+
Scalar profile inspection rejects an invalid stored binding. Structured
|
|
862
|
+
inspection remains available and reports invalid effective IDs as `null` with
|
|
863
|
+
an `error`; invalid list bindings carry `binding_error`, and show bindings carry
|
|
864
|
+
`binding.error`. Their invalid stored tenant IDs are redacted as `null`.
|
|
790
865
|
|
|
791
866
|
Every command that reports a result prints one JSON document to standard
|
|
792
867
|
output by default, with progress notes and diagnostics on standard error,
|
|
793
|
-
so the JSON stays parseable in scripts; `--output table`
|
|
794
|
-
table instead.
|
|
868
|
+
so the JSON stays parseable in scripts; where supported, `--output table`
|
|
869
|
+
prints a readable table instead. `aac sso describe` supports JSON only.
|
|
870
|
+
The three profile writers are the exception: `aac profile
|
|
795
871
|
create`, `update` and `delete` confirm on standard error, leave standard
|
|
796
872
|
output empty and take no `--output`.
|
|
797
873
|
|
|
@@ -802,6 +878,18 @@ output empty and take no `--output`.
|
|
|
802
878
|
| `2` | Usage error: an invalid flag, value or flag combination. |
|
|
803
879
|
| `3` | A local configuration or state problem: profile, credential file, cached session or agent. |
|
|
804
880
|
| `4` | Transport failure: an endpoint could not be reached. |
|
|
881
|
+
| `130` | Interrupted by the operator (Ctrl-C). |
|
|
882
|
+
|
|
883
|
+
Ctrl-C stops `aac` and CLI-owned `aeg` without a traceback, with one concise
|
|
884
|
+
diagnostic on standard error. A remote change may already have committed;
|
|
885
|
+
follow any recovery guidance and retain pending registration or key-operation
|
|
886
|
+
state. The CLI does not roll back or automatically retry a remote change.
|
|
887
|
+
|
|
888
|
+
Walking away from sign-in retains the existing deadlines: device sign-in waits
|
|
889
|
+
for the identity provider's device-code lifetime (300 seconds if absent), then
|
|
890
|
+
exits `1` with instructions to run login again; a PKCE browser sign-in without
|
|
891
|
+
a callback gives up after 300 seconds with exit `3`. HTTP timeouts remain exit
|
|
892
|
+
`4`. These outcomes are distinct from Ctrl-C; there is no shorter patience cap.
|
|
805
893
|
|
|
806
894
|
If AAC asks you to slow down, the command shows the interval to wait. The
|
|
807
895
|
CLI never replays a change on its own; wait and rerun deliberately.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""`python -m aac_cli` — same entrypoint as the `aac` console script."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
from aac_cli.cli import entrypoint
|
|
7
|
+
|
|
8
|
+
if __name__ == "__main__":
|
|
9
|
+
entrypoint()
|
|
10
|
+
except KeyboardInterrupt:
|
|
11
|
+
# The shared command boundary is not loaded during early imports.
|
|
12
|
+
sys.stderr.write("aac: interrupted\n")
|
|
13
|
+
raise SystemExit(130) from None
|
|
@@ -7,6 +7,7 @@ import sys
|
|
|
7
7
|
from importlib.resources import files
|
|
8
8
|
|
|
9
9
|
from . import __version__
|
|
10
|
+
from .interrupts import run_command
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def version_text() -> str:
|
|
@@ -15,6 +16,10 @@ def version_text() -> str:
|
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
def main(argv: list[str] | None = None) -> int:
|
|
19
|
+
return run_command(lambda: _main(argv), prog="aeg")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _main(argv: list[str] | None = None) -> int:
|
|
18
23
|
argv = list(sys.argv[1:] if argv is None else argv)
|
|
19
24
|
if argv == ["--version"]:
|
|
20
25
|
print(version_text())
|
|
@@ -619,13 +619,21 @@ def cmd_agent_list(args: argparse.Namespace) -> int:
|
|
|
619
619
|
row["certificates"] = case_for(record.material_source).name
|
|
620
620
|
tenant = tenant_paths(record.tenant_id) if record.tenant_id else None
|
|
621
621
|
health = assess(agent, tenant, record)
|
|
622
|
+
row["profile_binding_consistent"] = health.profile_binding_consistent
|
|
622
623
|
row["next_command"] = next_step(agent, tenant, record, health)
|
|
623
624
|
rows.append(row)
|
|
624
625
|
if args.output == "table":
|
|
625
626
|
if not rows:
|
|
626
627
|
print(f"no agents under {directory}")
|
|
627
628
|
for row in rows:
|
|
628
|
-
|
|
629
|
+
binding_note = (
|
|
630
|
+
" (profile binding inconsistent)"
|
|
631
|
+
if row.get("profile_binding_consistent") is False
|
|
632
|
+
else ""
|
|
633
|
+
)
|
|
634
|
+
print(
|
|
635
|
+
f"{row['agent']:<16}: {row.get('certificates', row.get('state', '-'))}{binding_note}"
|
|
636
|
+
)
|
|
629
637
|
return 0
|
|
630
638
|
print(json.dumps({"agents": rows}, indent=2))
|
|
631
639
|
return 0
|
|
@@ -708,7 +716,12 @@ def add_agent_parser(nouns: argparse._SubParsersAction) -> None:
|
|
|
708
716
|
listing = verbs.add_parser(
|
|
709
717
|
"list",
|
|
710
718
|
help="List every agent under the CLI home with its tenant, case and state.",
|
|
711
|
-
description=
|
|
719
|
+
description=(
|
|
720
|
+
"List every agent; an unreadable or unsupported record is reported in that "
|
|
721
|
+
"agent's state without hiding the other agents. Invalid profile bindings "
|
|
722
|
+
"are reported per agent: JSON includes profile_binding_consistent and the "
|
|
723
|
+
"repair next_command; table output marks inconsistent bindings."
|
|
724
|
+
),
|
|
712
725
|
)
|
|
713
726
|
listing.add_argument(
|
|
714
727
|
"--output", choices=("json", "table"), default="json", help="Output mode (JSON by default)."
|
|
@@ -22,7 +22,13 @@ from aac_cli.agent_layout import (
|
|
|
22
22
|
material_inventory,
|
|
23
23
|
)
|
|
24
24
|
from aac_cli.agent_record import STEP_MATERIAL, AgentRecord
|
|
25
|
-
from aac_cli.config import
|
|
25
|
+
from aac_cli.config import (
|
|
26
|
+
CliConfigError,
|
|
27
|
+
cli_home,
|
|
28
|
+
credentials_path,
|
|
29
|
+
profile_binding_error,
|
|
30
|
+
read_profile_section,
|
|
31
|
+
)
|
|
26
32
|
from aac_cli.material_cases import MATERIAL_ISSUED_HERE, MATERIAL_SUPPLIED, ca_report_label
|
|
27
33
|
from aac_cli.secure_files import managed_path_problem
|
|
28
34
|
|
|
@@ -40,6 +46,7 @@ class CertificateReport:
|
|
|
40
46
|
class AgentHealth:
|
|
41
47
|
setup_complete: bool
|
|
42
48
|
profile_binding_consistent: bool
|
|
49
|
+
invalid_profile_binding: bool = False
|
|
43
50
|
missing_files: list[str] = field(default_factory=list)
|
|
44
51
|
permission_problems: list[str] = field(default_factory=list)
|
|
45
52
|
certificates: dict[str, CertificateReport] = field(default_factory=dict)
|
|
@@ -74,7 +81,9 @@ class AgentHealth:
|
|
|
74
81
|
reasons: list[str] = []
|
|
75
82
|
if not self.setup_complete:
|
|
76
83
|
reasons.append("setup is incomplete")
|
|
77
|
-
if
|
|
84
|
+
if self.invalid_profile_binding:
|
|
85
|
+
reasons.append("the profile has an invalid stored tenant binding")
|
|
86
|
+
elif not self.profile_binding_consistent:
|
|
78
87
|
reasons.append("the profile is bound to a different tenant than this agent")
|
|
79
88
|
reasons.extend(f"missing: {name}" for name in self.missing_files)
|
|
80
89
|
reasons.extend(self.permission_problems)
|
|
@@ -111,10 +120,16 @@ def _certificate_reports(
|
|
|
111
120
|
|
|
112
121
|
def assess(agent: AgentPaths, tenant: TenantPaths | None, record: AgentRecord) -> AgentHealth:
|
|
113
122
|
"""The offline health assessment both `status` and a completed `init` report."""
|
|
114
|
-
|
|
123
|
+
# Offline inventory diagnoses this agent's profile without allowing one
|
|
124
|
+
# stale association to abort every other agent's inventory. Operational
|
|
125
|
+
# profile resolution stays strict; material paths use the validated record.
|
|
126
|
+
stored = read_profile_section(record.profile, validate_binding=False)
|
|
127
|
+
invalid_binding = profile_binding_error(stored) is not None
|
|
115
128
|
health = AgentHealth(
|
|
116
129
|
setup_complete=record.next_step() is None,
|
|
117
|
-
profile_binding_consistent=
|
|
130
|
+
profile_binding_consistent=not invalid_binding
|
|
131
|
+
and stored.get("tenant_id") == record.tenant_id,
|
|
132
|
+
invalid_profile_binding=invalid_binding,
|
|
118
133
|
)
|
|
119
134
|
if tenant is None:
|
|
120
135
|
return health
|
|
@@ -387,6 +402,8 @@ def next_step(
|
|
|
387
402
|
) -> str | None:
|
|
388
403
|
"""The one next step `status` reports and a refused `init` names; None when there is none."""
|
|
389
404
|
agent_flag = f"--agent {_quote(agent.name)}"
|
|
405
|
+
if health.invalid_profile_binding:
|
|
406
|
+
return f"aac profile update {_quote(record.profile)} --unbind"
|
|
390
407
|
if not health.setup_complete:
|
|
391
408
|
return f"aac init --profile {_quote(record.profile)} {agent_flag}"
|
|
392
409
|
if tenant is not None:
|