## Summary - Adds the Spec 431 Exchange PowerShell invocation gate and operation registration slice. - Introduces trusted provider operation start handling and read-only Exchange PowerShell runner abstractions. - Updates provider capability/readiness evaluation and coverage for Exchange PowerShell invocation safety. ## Verification - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Providers/ProviderCapabilityEvaluationTest.php tests/Feature/Providers/ProviderOperationCapabilityGateTest.php tests/Feature/TenantConfiguration/Spec431ExchangePowerShellInvocationGateTest.php tests/Unit/Providers/ProviderCapabilityRegistryTest.php tests/Unit/Providers/ProviderOperationStartGateTest.php tests/Unit/Support/TenantConfiguration/Spec430ExchangePowerShellCommandAllowlistTest.php tests/Unit/Support/TenantConfiguration/Spec431ExchangePowerShellOperationRegistrationTest.php tests/Unit/Verification/ManagedEnvironmentPermissionCapabilityMappingTest.php` - Result: 80 passed, 685 assertions. ## Product Surface / Ops - Rendered UI surface changed: N/A. - Filament/Livewire surface changed: N/A. - Deployment impact: config/runtime service changes only; no migrations, queues, or assets added. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #498
112 lines
10 KiB
Markdown
112 lines
10 KiB
Markdown
# Tasks: Exchange PowerShell Invocation Operation Registration and Execution Gate
|
|
|
|
**Input**: Design documents from `specs/431-exchange-powershell-invocation-operation-registration-gate/`
|
|
**Prerequisites**: `spec.md`, `plan.md`, Spec 430 implementation report, current repo source truth
|
|
**Tests**: Required. Runtime behavior changes must use Pest 4 focused unit/feature tests and selected regressions.
|
|
|
|
## Test Governance Checklist
|
|
|
|
- [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
|
|
- [x] New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
|
|
- [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
|
|
- [x] Planned validation commands cover the change without pulling in unrelated lane cost.
|
|
- [x] Browser proof is explicitly `N/A - no rendered UI surface changed`.
|
|
- [x] Human Product Sanity and Product Surface implementation-report close-out are planned as N/A.
|
|
- [x] Any material budget, baseline, trend, or escalation note is recorded in the implementation report.
|
|
|
|
## Phase 1: Preflight
|
|
|
|
- [x] T001 Capture current branch, HEAD, and `git status --short`.
|
|
- [x] T002 Confirm Spec 430 implementation report proves `transportRule`, `remoteDomain`, and `inboundConnector` command contracts and no OperationRun/evidence/UI/migration.
|
|
- [x] T003 Confirm no existing `tenant_configuration.exchange_powershell_invocation` operation type/catalog entry/provider operation/provider capability exists.
|
|
- [x] T004 Confirm allowed summary keys in `apps/platform/app/Support/OpsUx/OperationSummaryKeys.php` and unknown-key drop behavior in `SummaryCountsNormalizer`.
|
|
- [x] T005 Confirm hard stop boundaries: no live provider execution, no evidence, no UI, no migration, no scheduled capture/jobs, no `tenant_id`, no mini-platform.
|
|
|
|
## Phase 2: Operation Registration
|
|
|
|
- [x] T006 Add the canonical OperationRun type in `apps/platform/app/Support/OperationRunType.php`, using `tenant_configuration.exchange_powershell_invocation` unless repo convention forces a documented equivalent.
|
|
- [x] T007 Add the OperationCatalog canonical definition and canonical alias/write entry in `apps/platform/app/Support/OperationCatalog.php`.
|
|
- [x] T008 Add unit tests proving OperationRunType and OperationCatalog recognize the invocation operation and keep it internal/no-customer-claim.
|
|
|
|
## Phase 3: Provider Operation and Capability
|
|
|
|
- [x] T009 Add a ProviderOperationRegistry definition mapping the provider operation to the canonical invocation operation and internal module label.
|
|
- [x] T010 Add a provider binding that is explicit for Microsoft/Exchange PowerShell and does not imply evidence/capture readiness.
|
|
- [x] T011 Add or map one provider capability in `ProviderCapabilityRegistry`, recommended as `exchange_powershell_invoke` or repo-canonical equivalent.
|
|
- [x] T012 Add or update tests proving registry mapping, active/unsupported binding behavior, required provider capability keys, and capability registry lookup.
|
|
|
|
## Phase 4: Actor Capability Resolution
|
|
|
|
- [x] T013 Add `OperationRunCapabilityResolver` execution mapping for the invocation operation to existing `App\Support\Auth\Capabilities::PROVIDER_RUN`; do not add a new actor capability unless the spec is amended first.
|
|
- [x] T014 Add tests proving required actor capability resolution to `Capabilities::PROVIDER_RUN` and fail-closed behavior when capability is missing or unresolved.
|
|
- [x] T015 Ensure tests prove readonly actors cannot invoke, members missing `Capabilities::PROVIDER_RUN` receive 403, and non-member/not-entitled scope remains 404.
|
|
|
|
## Phase 5: Summary Counts and Failure Sanitization
|
|
|
|
- [x] T016 Implement the summary strategy using existing keys where possible: `total`, `processed`, `succeeded`, `failed`, `skipped`, `items`.
|
|
- [x] T017 Add new summary keys only if existing keys cannot represent required counts; if added, update `OperationSummaryKeys` and tests.
|
|
- [x] T018 Add tests proving emitted keys are preserved, unknown keys are dropped, values are numeric-only, and no raw output appears in summary counts.
|
|
- [x] T019 Add or map invocation blocker/failure reasons through `RunFailureSanitizer` or known provider reason codes.
|
|
- [x] T020 Add tests covering known invocation blocker, known invocation failure, unknown invocation failure, raw exception with token-like text, and stderr-like text with secret-like content.
|
|
|
|
## Phase 6: Invocation Gate
|
|
|
|
- [x] T021 Add one invocation gate service under the repo-canonical TenantConfiguration/provider service path, likely `apps/platform/app/Services/TenantConfiguration/ExchangePowerShellInvocationGate.php`, and make it the sole public entry point for Spec 431 invocation.
|
|
- [x] T022 Gate target types to exactly `transportRule`, `remoteDomain`, and `inboundConnector`.
|
|
- [x] T023 Gate command contracts to exactly `Get-TransportRule`, `Get-RemoteDomain`, and `Get-InboundConnector`.
|
|
- [x] T024 Require Spec 430 `contract_verified_pending_capture` and `adapter_contract_available` state from `CoverageSourceContractResolver`.
|
|
- [x] T025 Require OperationRun type/catalog/provider operation/provider capability/capability resolver registration before runner execution.
|
|
- [x] T026 Require workspace, managed environment, provider connection, actor/context, operation type, feature gate `tenantpilot.features.exchange_powershell_invocation` defaulting false, runner mode, redaction policy, `Capabilities::PROVIDER_RUN`, and existing provider credential/identity resolution unless fake-runner-only mode explicitly bypasses live credentials.
|
|
- [x] T027 Reuse or compose with `ProviderOperationStartGate` internally where practical so provider binding/capability/scope behavior stays central; do not expose direct runner calls or direct provider-start-gate invocation as a public Exchange PowerShell invocation path.
|
|
- [x] T028 Create/reuse OperationRun before fake runner execution and route status/outcome transitions only through `OperationRunService`.
|
|
- [x] T029 Add gate tests for success, default feature disabled, controlled test feature enablement, missing `Capabilities::PROVIDER_RUN`, missing provider capability, missing provider credential/identity reference, invalid provider scope, invalid target type, invalid command, unknown parameters, direct runner bypass rejection, and direct provider-start-gate bypass rejection.
|
|
|
|
## Phase 7: Runner Boundary
|
|
|
|
- [x] T030 Add structured runner interface, likely `ExchangePowerShellCommandRunner`, accepting structured command contract, invocation context, timeout policy, and redaction policy.
|
|
- [x] T031 Ensure the runner interface rejects raw command strings, script blocks, pipelines, arbitrary parameters, shell fragments, semicolon-separated commands, redirection, file writes, and module installation commands.
|
|
- [x] T032 Add fake runner supporting success, empty result, authentication failure, authorization failure, permission failure, timeout, throttling, module unavailable, command unavailable, malformed result, and unexpected exception.
|
|
- [x] T033 Add disabled/inert production runner only if needed; default must return `execution_blocked_runner_disabled` or repo-equivalent without PowerShell or Microsoft calls.
|
|
- [x] T034 Add tests proving no PowerShell process starts and no Microsoft service call is made.
|
|
|
|
## Phase 8: Shape Validation and Redaction
|
|
|
|
- [x] T035 Validate structured collection-compatible results for each included command.
|
|
- [x] T036 Treat empty collection as valid empty success only when the runner envelope is success.
|
|
- [x] T037 Ensure permission/authorization failures are not treated as empty success.
|
|
- [x] T038 Fail safely on malformed scalar/text output and missing identity candidate fields.
|
|
- [x] T039 Add redaction tests proving OperationRun context excludes raw stdout, raw stderr, provider payloads, transcripts, raw exceptions, tokens, secrets, cookies, authorization headers, certificate material, mail body, message content, mailbox content, and file content.
|
|
- [x] T040 Prove `provider_connection_id` is stored only in sanitized OperationRun context and no `operation_runs.provider_connection_id` migration exists.
|
|
|
|
## Phase 9: No-Promotion and No-Surface Guards
|
|
|
|
- [x] T041 Add tests proving no `tenant_configuration_resource_evidence` rows are created.
|
|
- [x] T042 Add tests proving no raw evidence payload or normalized evidence payload is persisted.
|
|
- [x] T043 Add tests proving no content-backed, comparable, renderable, certified, restore-ready, customer-ready, report, Review Pack, or customer claim state appears.
|
|
- [x] T044 Add tests or guard scans proving no route, Filament page, Livewire component, navigation item, global search change, asset change, or browser surface is introduced.
|
|
- [x] T045 Add tests or guard scans proving no `tenant_id`, Exchange-specific evidence table, legacy shim, fallback reader, dual-write path, or Exchange mini-platform is introduced.
|
|
|
|
## Phase 10: Regression and Validation
|
|
|
|
- [x] T046 Run focused Spec 431 unit and feature tests.
|
|
- [x] T047 Run Spec 430 adapter contract regression tests.
|
|
- [x] T048 Run selected Spec 426 and Spec 427 no-promotion/source-contract regressions.
|
|
- [x] T049 Run selected Spec 417, Spec 419, and Spec 420 identity/registry/generic evidence regressions where available.
|
|
- [x] T050 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`.
|
|
- [x] T051 Run `git diff --check`.
|
|
- [x] T052 Capture final `git status --short`.
|
|
|
|
## Phase 11: Implementation Report
|
|
|
|
- [x] T053 Complete `specs/431-exchange-powershell-invocation-operation-registration-gate/implementation-report.md` with candidate gate result, branch/HEAD, dirty state, files changed, proportionality review, operation registration proof, provider/capability proof, `Capabilities::PROVIDER_RUN` resolver proof, feature-gate key/default proof, credential-source proof, single-public-gate proof, summary/failure proof, runner/fake-runner proof, production-disabled proof, command safety proof, provider scope proof, credential proof, shape validation proof, redaction proof, no shell/provider call proof, no evidence proof, no product promotion proof, no UI proof, no tenant_id proof, no mini-platform proof, Product Surface N/A decision, tests run, deferred work, and validation results.
|
|
|
|
## Explicit Non-Goals During Implementation
|
|
|
|
- [x] No live Exchange Online execution.
|
|
- [x] No PowerShell binary/process/module install.
|
|
- [x] No Microsoft service calls in tests.
|
|
- [x] No evidence persistence or promotion.
|
|
- [x] No UI/routes/navigation/global search/assets.
|
|
- [x] No migrations or `tenant_id`.
|
|
- [x] No Teams, Exchange Admin API, outboundConnector, acceptedDomain, organizationConfig, mailboxPlan, or sharingPolicy.
|