Add CNAPP integration commands and helpers#2102
Merged
Merged
Conversation
|
Hope to review this week, since not a priority today. |
b1183b7 to
b384cf6
Compare
fb233de to
e0e43d2
Compare
b11acff to
c6ec45e
Compare
1b4d5b9 to
00cb187
Compare
7fd6385 to
2ddc839
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds a new pam cnapp ... command tree plus a helper/proto layer to let Commander drive krouter’s CNAPP endpoints (initial provider: Wiz), including optional client-side AES-256-GCM payload decryption and a comprehensive unit test suite.
Changes:
- Introduces CNAPP protobuf bindings and a helper module that builds/dispatches CNAPP proto requests to krouter.
- Adds
pam cnappCLI commands for configuration management and queue operations (list/associate/remediate/set-status/delete), with--format table|jsonon read/list. - Adds unit tests covering helper request shaping, command argument handling, output rendering, and AES-GCM payload decryption behavior.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
keepercommander/commands/discoveryrotation.py |
Wires the new pam cnapp command tree into the existing PAM command group. |
keepercommander/commands/pam/cnapp_commands.py |
Implements the argparse-driven CNAPP command surface, output formatting, and payload decryption/key-resolution. |
keepercommander/commands/pam/cnapp_helper.py |
Provides endpoint-specific helper functions as the single source of truth for CNAPP krouter wire contracts. |
keepercommander/proto/cnapp_pb2.py |
Adds generated protobuf bindings for CNAPP request/response messages and enums. |
unit-tests/pam/test_cnapp.py |
Adds unit tests for enum parsing, helper calls, command behaviors, and payload decryption. |
unit-tests/conftest.py |
Adds a pytest session fixture to preload keepercommander.commands.record to avoid an import cycle in tests. |
unit-tests/pam/test_dag_layer_b_migration.py |
Adds a regression test ensuring AI settings requests bundle meta so krouter persists settings edges correctly. |
Files not reviewed (1)
- keepercommander/proto/cnapp_pb2.py: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
19
to
23
| from datetime import datetime | ||
| from typing import Dict, Optional, Any, Set, List | ||
| from urllib.parse import urlparse, urlunparse | ||
| from typing import Optional, List | ||
|
|
Comment on lines
+68
to
+70
| """Encrypter keys are typically `openssl rand -base64 32`. Try standard base64 first, | ||
| then base64url (legacy notes). 16 or 32 bytes only — anything else is rejected so we | ||
| don't pass garbage to AES-GCM.""" |
Comment on lines
+107
to
+116
| for raw in labeled_raws: | ||
| key = _decode_aes_key(raw) | ||
| if key: | ||
| return key | ||
| logging.warning( | ||
| 'CNAPP: "%s" field is present on encrypter record %s but is not a valid AES-256 key; ' | ||
| 'not using other note fields.', | ||
| CNAPP_ENCRYPTION_KEY_LABEL, config_record_uid, | ||
| ) | ||
| return None |
Comment on lines
+746
to
+747
| """`_decode_aes_key` must accept both standard and url-safe base64, only when the | ||
| decoded length is 16 or 32 bytes.""" |
This comment has been minimized.
This comment has been minimized.
Re-applied on top of origin/release after sync-branch. Includes CNAPP command helpers, PAM graph endpoint migration, and related unit test updates. Co-authored-by: Cursor <cursoragent@cursor.com>
Move SIEM Tool mock expiration to 2030 so status detection tests remain deterministic when CI runs in UTC after the token expiry date. Co-authored-by: Cursor <cursoragent@cursor.com>
idimov-keeper
approved these changes
Jul 8, 2026
craiglurey
approved these changes
Jul 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title
Add CNAPP integration commands and helpersSummary
Adds a new
pam cnapp ...command tree to Commander that drives the krouter CNAPP (Cloud-Native Application Protection Platform) REST endpoints, giving CLI parity with the vault's Cloud Security view. The initial provider is Wiz; the wire/proto layer is provider-agnostic so additional CNAPP vendors can be added without further CLI changes.Includes the protobuf definitions, a thin helper layer that owns the wire contract, the argparse-driven command surface, and a unit-test suite that exercises the real proto serializers against a mocked router transport.
Changes
keepercommander/commands/discoveryrotation.py— registerPAMCnappCommandunder thepamgroup with aliascn.keepercommander/commands/pam/cnapp_commands.py(new, 608 lines) — fullpam cnappcommand tree:pam cnapp config set | test | test-encrypter | read | delete— manage the provider configuration and health-check the customer-deployed Encrypter.pam cnapp queue list | associate | remediate | set-status | delete— drive the issue queue (list with optional payload decryption, attach a vault record, dispatch remediation to the gateway, update status, delete).decryptCnappQueueIteminvault/cloudSecurityUtils.tsso the CLI and vault see the same plaintext.--format table|jsonon read/list commands for scripting.keepercommander/commands/pam/cnapp_helper.py(new, 241 lines) — single source of truth for the krouter wire contract. One Python function per endpoint under/api/user/cnapp/, plus enum parsers (provider_from_name,action_from_name) and UID conversion utilities. Callers pass parsed Python types; the helper builds the proto, dispatches via_post_request_to_router, and returns the typed response.keepercommander/proto/cnapp_pb2.py(new, 181 lines) — generated protobuf bindings forcnapp.proto, coveringCnappConfiguration, queue request/response messages,CnappProvider(currentlyWIZ), andCnappRemediationAction(ROTATE_CREDENTIALS,MANAGE_ACCESS,JIT_ACCESS,REMOVE_STANDING_PRIVILEGE).unit-tests/pam/test_cnapp.py(new, 837 lines) — coverage for enum parsing, helper-level request shaping for every endpoint, command-level argument validation and output rendering (table + JSON), payload decryption (happy path + bad-key + missing-key fallback), and status-name → id resolution.Cross-references
/api/user/cnapp/...(configuration/{set,test,test-encrypter,read,delete},queue,queue/{associate,remediate,set-status,delete}).vault/cloudSecurityUtils.ts(CNAPP_ENCRYPTION_KEY_FIELD_LABEL = "Encryption Key",AES-256-GCMwithnonce(12) || ciphertext || tag(16)).CnappQueueStatusfromCnappModels.kt/keeper.cnapp_queue_status— new statuses must be added in both places.Notes / limitations
ROTATE_CREDENTIALS; the other remediation actions are wired through the proto but returnRRC_BAD_REQUESTserver-side until those flows are implemented.config readnever returnsclientSecret; passing an empty--client-secrettoconfig setinstructs krouter to keep the previously stored value.queue listfalls back to showing payloads asencrypted(with a warning) when no Encrypter key can be resolved from the linked vault record;--no-decryptopts out explicitly.Test plan
python -m unittest unit-tests.pam.test_cnapp -vpasses locally.pam cnapp config setpersists;pam cnapp config readreturns the same network/provider/endpoint/client-id (and no secret).pam cnapp config testsucceeds with valid creds and fails cleanly with the provider's reason on bad creds.pam cnapp config test-encrypter --url https://...returns OK for a healthy Encrypter and surfaces a clear error otherwise.pam cnapp queue list --network-uid ...renders the table with decrypted summaries (severity · title · resource) when the Encrypter record is in the vault; the same call with--no-decryptshowsencryptedand a warning.pam cnapp queue list --format jsonemits valid JSON withdecryptedPayloadpopulated and the rawpayloadfield stripped.pam cnapp queue associatethenpam cnapp queue remediate ... rotate_credentialsround-trips through the gateway andqueue listreflects the new status.pam cnapp queue set-status pending|in_progress|resolved|failed|cancelledand numeric ids both work; unknown names raise aCommandErrorlisting the valid options.pam cnapp config deleteandpam cnapp queue deletesucceed and subsequent reads return the expected empty/RRC_BAD_STATEresponses.