feat: add --format otel to scan command for ComplyBeacon evidence export#463
Merged
gvauter merged 10 commits intocomplytime:mainfrom Apr 21, 2026
Merged
feat: add --format otel to scan command for ComplyBeacon evidence export#463gvauter merged 10 commits intocomplytime:mainfrom
gvauter merged 10 commits intocomplytime:mainfrom
Conversation
jpower432
requested changes
Apr 6, 2026
Member
jpower432
left a comment
There was a problem hiding this comment.
I added a PR with a suggestion to your branch. I would like to find a way to avoid plugin author needs to Export stubs if they don't implement it. I think this additional feature should be fully opt in for the plugin author.
54f3f31 to
9a753d4
Compare
Member
Author
Great thanks Jenn, I've merged your PR. |
9a753d4 to
2ae7d72
Compare
77c4c7d to
f9337b7
Compare
marcusburghardt
added a commit
to marcusburghardt/org-infra
that referenced
this pull request
Apr 16, 2026
The post-comment job in ci_crapload.yml was skipped when the CRAP Load analysis detected regressions because the implicit success() condition on the needs dependency prevented it from running. This meant PR authors never saw the detailed report when they needed it most. Add if: !cancelled() so the comment job runs on both success and failure. Handle missing artifacts with a fallback comment linking to the Job Summary, and truncate oversized comments to stay within GitHub limits. Refs: complytime/complyctl#463 Assisted-by: OpenCode (claude-opus-4-6) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
marcusburghardt
added a commit
to complytime/org-infra
that referenced
this pull request
Apr 16, 2026
The post-comment job in ci_crapload.yml was skipped when the CRAP Load analysis detected regressions because the implicit success() condition on the needs dependency prevented it from running. This meant PR authors never saw the detailed report when they needed it most. Add if: !cancelled() so the comment job runs on both success and failure. Handle missing artifacts with a fallback comment linking to the Job Summary, and truncate oversized comments to stay within GitHub limits. Refs: complytime/complyctl#463 Assisted-by: OpenCode (claude-opus-4-6) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
Export was part of the Plugin interface, forcing every plugin to
carry a no-op stub even when it has no export capability. This
violates the Interface Segregation Principle and contradicts
FR-013 ("plugins that do not implement Export MUST NOT be required
to change").
Introduce a separate Exporter interface. The grpcServer adapter
performs a runtime type assertion so the proto-level Export RPC
still works on the wire. Plugin authors only implement Exporter
when they opt in via supports_export=true in DescribeResponse.
Made-with: Cursor
Signed-off-by: Jennifer Power <barnabei.jennifer@gmail.com>
Made-with: Cursor
f9337b7 to
ce70be4
Compare
Split runExport and formatExportSummary into smaller functions (resolveCollectorAuth, exportToPlugins, exportSinglePlugin, appendExportRow, appendResponseRow, exportResponseStatus, authRequired, validateAuthCredentials) so each stays below the CRAP threshold of 30 at 0% coverage. Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
ce70be4 to
a2f3c44
Compare
jpower432
previously approved these changes
Apr 20, 2026
Member
jpower432
left a comment
There was a problem hiding this comment.
LGTM. Tested E2E with a local collector and testing plugin.
runExport previously returned nil even when plugins reported export failures. User Story 1 Acceptance Scenario 4 requires a non-zero exit code when an unreachable collector or plugin-level failure occurs. Add countExportFailures to detect transport errors, Success==false, and FailedCount>0, then propagate an error from runExport. Add unit tests for export orchestration helpers (scan.go): authRequired, validateAuthCredentials, countExportFailures, exportResponseStatus, formatExportSummary, and the otel-without- collector early-exit path. Add unit tests for CheckCollector and checkCollectorAuth (doctor.go) covering nil collector, empty endpoint, valid endpoint with and without auth, and each incomplete-auth warning path. Assisted-by: OpenCode (claude-sonnet-4-6@default) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
Test fixtures use placeholder credentials, not real secrets. Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor Signed-off-by: George Vauter <gvauter@redhat.com> Made-with: Cursor
c9d8fcf to
69ea907
Compare
marcusburghardt
approved these changes
Apr 21, 2026
Contributor
marcusburghardt
left a comment
There was a problem hiding this comment.
LGTM. Thanks @gvauter
marcusburghardt
added a commit
to marcusburghardt/complyctl
that referenced
this pull request
Apr 21, 2026
…ovider scan.go: Replace remaining pkg/plugin import alias usages in the export path (executeScanPhase, maybeExport, runExport, exportToPlugins, exportSinglePlugin, exportResult) with pkg/provider equivalents. cli_test.go: Update import from pkg/plugin to pkg/provider and rename all pluginID field references to providerID. These references were missed during the pkg/plugin → pkg/provider rename because upstream's Export RPC additions (PR complytime#463) landed in the same functions during the rebase, leaving a mix of old and new package names. Assisted-by: OpenCode (claude-sonnet-4-6@default) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
marcusburghardt
added a commit
to marcusburghardt/complyctl
that referenced
this pull request
Apr 21, 2026
…ovider scan.go: Replace remaining pkg/plugin import alias usages in the export path (executeScanPhase, maybeExport, runExport, exportToPlugins, exportSinglePlugin, exportResult) with pkg/provider equivalents. cli_test.go: Update import from pkg/plugin to pkg/provider and rename all pluginID field references to providerID. These references were missed during the pkg/plugin → pkg/provider rename because upstream's Export RPC additions (PR complytime#463) landed in the same functions during the rebase, leaving a mix of old and new package names. Assisted-by: OpenCode (claude-sonnet-4-6@default) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
marcusburghardt
added a commit
to marcusburghardt/complyctl
that referenced
this pull request
Apr 22, 2026
Export WorkspaceDir from pkg/provider so provider authors can import the canonical workspace directory name instead of duplicating it locally. Providers in complytime-providers were hard-coding ".complytime" because internal/complytime.WorkspaceDir is not importable by external modules. Update contracts/provider-sdk.md to address review feedback (gvauter): - Remove Export from the Provider interface; Export is optional via the separate Exporter interface (ISP design finalised in PR complytime#463) - Add SupportsExport bool to DescribeResponse struct definition - Replace the stub implementation example with the correct opt-in pattern: implement Exporter + set SupportsExport: true in DescribeResponse - Update the contract stability table to list Exporter separately Assisted-by: OpenCode (claude-sonnet-4-6@default) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
marcusburghardt
added a commit
to marcusburghardt/complyctl
that referenced
this pull request
Apr 22, 2026
…ovider scan.go: Replace remaining pkg/plugin import alias usages in the export path (executeScanPhase, maybeExport, runExport, exportToPlugins, exportSinglePlugin, exportResult) with pkg/provider equivalents. cli_test.go: Update import from pkg/plugin to pkg/provider and rename all pluginID field references to providerID. These references were missed during the pkg/plugin → pkg/provider rename because upstream's Export RPC additions (PR complytime#463) landed in the same functions during the rebase, leaving a mix of old and new package names. Assisted-by: OpenCode (claude-sonnet-4-6@default) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
marcusburghardt
added a commit
to marcusburghardt/complyctl
that referenced
this pull request
Apr 22, 2026
Export WorkspaceDir from pkg/provider so provider authors can import the canonical workspace directory name instead of duplicating it locally. Providers in complytime-providers were hard-coding ".complytime" because internal/complytime.WorkspaceDir is not importable by external modules. Update contracts/provider-sdk.md to address review feedback (gvauter): - Remove Export from the Provider interface; Export is optional via the separate Exporter interface (ISP design finalised in PR complytime#463) - Add SupportsExport bool to DescribeResponse struct definition - Replace the stub implementation example with the correct opt-in pattern: implement Exporter + set SupportsExport: true in DescribeResponse - Update the contract stability table to list Exporter separately Assisted-by: OpenCode (claude-sonnet-4-6@default) Signed-off-by: Marcus Burghardt <maburgha@redhat.com>
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.
Summary
Implements the ComplyBeacon evidence export feature as specified in spec 003. This adds otel as a new output format for the complyctl scan command, enabling compliance evidence to be exported to a ComplyBeacon collector (or any OTLP-compatible endpoint) as OpenTelemetry log records.
When --format otel is specified, complyctl scan runs the scan as usual, then initiates an export phase where it calls each plugin's new Export RPC. The collector endpoint and optional OIDC client credentials are configured in complytime.yaml. Plugin stubs are included for OpenSCAP, AMPEL, and the test plugin — real ProofWatch-based implementations will follow in a subsequent PR.
Related Issues
Review Hints
Best reviewed commit-by-commit in order — each commit is self-contained and builds on the previous:
Notes:
The scan command handles OIDC token exchange itself (via golang.org/x/oauth2/clientcredentials) and passes the resolved bearer token to plugins in the ExportRequest. Plugins never see client credentials directly.
All plugin Export implementations are currently stubs that return Success: false. A follow-up PR will implement real export using ProofWatch in one or more plugins.
To test locally: configure a collector section in complytime.yaml with an endpoint, then run complyctl scan --policy-id --format otel. Without a collector configured, the command returns a clear error message. complyctl doctor will also report the collector configuration status.