Skip to content

Implement verifier receiver#1046

Closed
jeniawhite wants to merge 17 commits into
mainfrom
evgb-VerifierReceiver
Closed

Implement verifier receiver#1046
jeniawhite wants to merge 17 commits into
mainfrom
evgb-VerifierReceiver

Conversation

@jeniawhite
Copy link
Copy Markdown

@jeniawhite jeniawhite commented Feb 25, 2026

Implementation of a Verifier receiver to the Elastic distribution of OpenTelemetry (EDOT). The receiver checks that Cloud Connector–based integrations have the required cloud/identity provider permissions and reports results as OTEL logs to Elasticsearch.

Cloud Connector deployments need to know whether the configured IAM/API credentials have the permissions required by each integration. This receiver runs on-demand (or scheduled) verification: it performs minimal API calls per required permission, groups results by Cloud Connector, policy, and integration, and emits structured OTEL logs so users can see granted/denied/error status and fix missing permissions.

Replaces #1005 (reopened from a direct branch to enable CI checks).

@jeniawhite jeniawhite requested a review from a team as a code owner February 25, 2026 21:59
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new verifierreceiver module must be added to the excluded-modules list in versions.yaml (analogous to integrationreceiver which is also at v0.0.0).

Generated by PR Review Agent for issue #1046

Comment on lines +782 to +785
"InvalidAccessKeyId",
"SignatureDoesNotMatch",
"ExpiredToken",
"ExpiredTokenException",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟡 MEDIUM] ExpiredToken/ExpiredTokenException should not be classified as access denied

These error codes indicate transient credential issues (expired STS session, expired temporary credentials), not permanent permission denials. Classifying them as StatusDenied could mislead users into thinking they need IAM permission changes when they actually just need to refresh or re-assume their role credentials.

Consider moving these to the general error path (which returns StatusError) so the user sees "error" rather than "denied". The error code itself (ExpiredToken) would still be preserved in the result and is enough for the user to understand the root cause.

Suggested change
"InvalidAccessKeyId",
"SignatureDoesNotMatch",
"ExpiredToken",
"ExpiredTokenException",
"InvalidAccessKeyId",
"SignatureDoesNotMatch",

Comment on lines +494 to +497
case "GetMetricData":
// GetMetricData requires metric queries - use ListMetrics as proxy
_, err := client.ListMetrics(ctx, &cloudwatch.ListMetricsInput{})
return v.handleAWSError(err, "cloudwatch:GetMetricData")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟡 MEDIUM] Proxy verification checks a different IAM permission than claimed

ListMetrics verifies the cloudwatch:ListMetrics IAM permission, not cloudwatch:GetMetricData. A role could have the former without the latter, causing the verifier to report "granted" for GetMetricData when the permission is actually missing.

The same pattern applies to verifySQS below, where sqs:ListQueues is used to proxy-verify sqs:ReceiveMessage/sqs:DeleteMessage.

The S3 GetObject handler (line 424) sets an Endpoint string that explains the proxy: "s3:GetObject (verified via HeadBucket ...)". Consider doing the same here to surface the limitation in the verification result, e.g.:

Suggested change
case "GetMetricData":
// GetMetricData requires metric queries - use ListMetrics as proxy
_, err := client.ListMetrics(ctx, &cloudwatch.ListMetricsInput{})
return v.handleAWSError(err, "cloudwatch:GetMetricData")
case "GetMetricData":
// GetMetricData requires metric queries - use ListMetrics as proxy
_, err := client.ListMetrics(ctx, &cloudwatch.ListMetricsInput{})
result := v.handleAWSError(err, "cloudwatch:GetMetricData (verified via ListMetrics - different IAM permission)")
return result

- gomod: github.com/elastic/opentelemetry-collector-components/receiver/integrationreceiver v0.0.0
- gomod: github.com/elastic/opentelemetry-collector-components/receiver/loadgenreceiver v0.20.0
- gomod: github.com/elastic/opentelemetry-collector-components/receiver/elasticapmintakereceiver v0.20.0
- gomod: github.com/elastic/opentelemetry-collector-components/receiver/verifierreceiver v0.0.0
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟡 MEDIUM] New module missing from versions.yaml

The verifierreceiver module (at v0.0.0) is not listed in versions.yaml, but the similarly-versioned integrationreceiver is added to excluded-modules there. Missing this entry may cause the release/versioning tooling (push-tags target) to fail or skip tagging this module.

Add it to excluded-modules:

  - github.com/elastic/opentelemetry-collector-components/receiver/verifierreceiver

Comment thread receiver/verifierreceiver/receiver.go Outdated
if r.cancelFn != nil {
r.cancelFn()
}
r.wg.Wait()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚪ LOW] Shutdown doesn't respect the context deadline

r.wg.Wait() blocks without selecting on ctx.Done(). The OTel collector passes a context with a shutdown timeout here. Although r.cancelFn() is called first (which should make the verification goroutine exit promptly), if the in-flight AWS API call is slow to honor cancellation, Shutdown could block past the collector's deadline.

Consider using a select pattern or context.AfterFunc to handle the timeout:

done := make(chan struct{})
go func() {
    r.wg.Wait()
    close(done)
}()
select {
case <-done:
case <-ctx.Done():
    r.logger.Warn("Shutdown deadline exceeded while waiting for verification to complete")
}

@gregkalapos
Copy link
Copy Markdown
Contributor

I could review this from the general opentelemetry-collector-components, but certainly not for the specifics of how it works. Could maybe someone from your team @jeniawhite review the specific code? So my proposal would be that I can give an ok to merge into this repo, but then someone more familiar with the domain also looks at the specific logic as well. Would that be ok?

Few questions from my side:

  • Why should this be in this repo and should it be part of the default EDOT distribution?
    • Asking to see how we put this here. Also depending on the answer you may need additional PRs in elastic agent.
  • Somewhat related: what's when the collector doesn't run in any of those cloud environments? I see this'd print warnings when InitializeVerifier fails. Just wanna make sure this behaves properly in environments where this receiver has nothing to do - especially if this'd be by default part of EDOT. I looked a bit at receiver_test.go‎ and it's not clear to me that e.g. in a plain docker container (where from what I understand this receiver should't do anything), our EDOT collector would behave 100% the same with and without this receiver.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 725fb07 and 3a08f02.

📒 Files selected for processing (10)
  • receiver/verifierreceiver/config.go
  • receiver/verifierreceiver/config_test.go
  • receiver/verifierreceiver/factory_test.go
  • receiver/verifierreceiver/receiver.go
  • receiver/verifierreceiver/receiver_test.go
  • receiver/verifierreceiver/testdata/TESTING.md
  • receiver/verifierreceiver/testdata/test-aws.yaml
  • receiver/verifierreceiver/testdata/test-azure.yaml
  • receiver/verifierreceiver/testdata/test-gcp.yaml
  • receiver/verifierreceiver/testdata/test-standalone.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • receiver/verifierreceiver/factory_test.go

📝 Walkthrough

Walkthrough

Adds a new verifierreceiver component and Go module under receiver/verifierreceiver: package documentation, config model, factory, Logs receiver implementation, verifier registry, concrete verifiers for AWS/Azure/GCP, a permission registry with versioned permissions, OTEL log builders/metadata, extensive tests and testdata/example configs, go.mod and Makefile include, metadata.yaml, distribution manifest replacements, and a CODEOWNERS entry.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch evgb-VerifierReceiver

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@receiver/verifierreceiver/registry.go`:
- Around line 838-866: registerOktaIntegrations currently advertises Okta
integrations but there is no Okta verifier factory registered, causing
VerifierNotInitialized errors; either wire the Okta verifier factory into the
verifier registration flow (the same place that registers other verifiers in
receiver.go—i.e., add a call to register the Okta verifier factory so policies
for provider verifier.ProviderOkta are supported) or remove/disable the Okta
entries in PermissionRegistry.registerOktaIntegrations (calls to
r.register("okta_system", ...) and r.register("okta_users", ...)) until the
verifier implementation and its factory registration are added.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2de43db and fbeee3c.

⛔ Files ignored due to path filters (1)
  • receiver/verifierreceiver/go.sum is excluded by !**/*.sum
📒 Files selected for processing (33)
  • .github/CODEOWNERS
  • distributions/elastic-components/manifest.yaml
  • receiver/verifierreceiver/Makefile
  • receiver/verifierreceiver/README.md
  • receiver/verifierreceiver/config.go
  • receiver/verifierreceiver/config_test.go
  • receiver/verifierreceiver/doc.go
  • receiver/verifierreceiver/factory.go
  • receiver/verifierreceiver/factory_test.go
  • receiver/verifierreceiver/generated_component_test.go
  • receiver/verifierreceiver/generated_package_test.go
  • receiver/verifierreceiver/go.mod
  • receiver/verifierreceiver/internal/metadata/generated_logs.go
  • receiver/verifierreceiver/internal/metadata/generated_logs_test.go
  • receiver/verifierreceiver/internal/metadata/generated_status.go
  • receiver/verifierreceiver/internal/verifier/aws_verifier.go
  • receiver/verifierreceiver/internal/verifier/azure_verifier.go
  • receiver/verifierreceiver/internal/verifier/gcp_verifier.go
  • receiver/verifierreceiver/internal/verifier/verifier.go
  • receiver/verifierreceiver/metadata.yaml
  • receiver/verifierreceiver/receiver.go
  • receiver/verifierreceiver/receiver_test.go
  • receiver/verifierreceiver/registry.go
  • receiver/verifierreceiver/testdata/TESTING.md
  • receiver/verifierreceiver/testdata/agent-simulation.yaml
  • receiver/verifierreceiver/testdata/config.yaml
  • receiver/verifierreceiver/testdata/expected-logs.yaml
  • receiver/verifierreceiver/testdata/otel-config.yaml
  • receiver/verifierreceiver/testdata/templates/verifier.yaml
  • receiver/verifierreceiver/testdata/test-aws.yaml
  • receiver/verifierreceiver/testdata/test-azure.yaml
  • receiver/verifierreceiver/testdata/test-gcp.yaml
  • receiver/verifierreceiver/testdata/test-standalone.yaml

Comment thread receiver/verifierreceiver/registry.go Outdated
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated by PR Review Agent for issue #1046

Comment on lines +378 to +385
var tokenErr *oauth2.RetrieveError
if errors.As(err, &tokenErr) {
return Result{
Status: StatusDenied,
ErrorCode: "AuthenticationFailed",
ErrorMessage: err.Error(),
Endpoint: endpoint,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚪ LOW] oauth2.RetrieveError unconditionally classified as denied

oauth2.RetrieveError wraps any non-2xx HTTP response from the token endpoint, including server-side errors (5xx). Classifying a GCP STS outage as StatusDenied / AuthenticationFailed would send users troubleshooting IAM configuration instead of waiting for the service to recover.

Consider inspecting tokenErr.Response.StatusCode and only returning StatusDenied for 401/403:

Suggested change
var tokenErr *oauth2.RetrieveError
if errors.As(err, &tokenErr) {
return Result{
Status: StatusDenied,
ErrorCode: "AuthenticationFailed",
ErrorMessage: err.Error(),
Endpoint: endpoint,
}
var tokenErr *oauth2.RetrieveError
if errors.As(err, &tokenErr) {
if tokenErr.Response != nil && (tokenErr.Response.StatusCode == 401 || tokenErr.Response.StatusCode == 403) {
return Result{
Status: StatusDenied,
ErrorCode: "AuthenticationFailed",
ErrorMessage: err.Error(),
Endpoint: endpoint,
}
}
return Result{
Status: StatusError,
ErrorCode: "TokenRetrievalError",
ErrorMessage: err.Error(),
Endpoint: endpoint,
}
}

Comment thread receiver/verifierreceiver/doc.go Outdated
Comment on lines +28 to +29
// - Azure (planned): Activity Logs, Audit Logs, Blob Storage
// - GCP (planned): Audit Logs, Cloud Storage, Pub/Sub
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💬 NITPICK] Azure and GCP are listed as "planned" but are implemented

Both azure_verifier.go and gcp_verifier.go contain full implementations (credential setup, API calls, error handling). These should be marked as "active" to match the actual state of the code. Same applies to the README table.

// Default credentials mode (testing): uses the default AWS credential chain.
func NewAWSVerifier(ctx context.Context, logger *zap.Logger, authConfig AWSAuthConfig) (*AWSVerifier, error) {
httpClient := &http.Client{
Transport: http.DefaultTransport.(*http.Transport).Clone(),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚪ LOW] Unchecked type assertion on http.DefaultTransport

http.DefaultTransport is typed as http.RoundTripper. If any library, test helper, or observability instrumentation replaces it with a non-*http.Transport wrapper, this assertion will panic and crash the collector.

Suggested change
Transport: http.DefaultTransport.(*http.Transport).Clone(),
transport, _ := http.DefaultTransport.(*http.Transport)
if transport == nil {
transport = &http.Transport{}
}
httpClient := &http.Client{
Transport: transport.Clone(),
}

@jeniawhite
Copy link
Copy Markdown
Author

jeniawhite commented Feb 28, 2026

@gregkalapos

Could maybe someone from your team @jeniawhite review the specific code? So my proposal would be that I can give an ok to merge into this repo, but then someone more familiar with the domain also looks at the specific logic as well. Would that be ok?

Yes, this is the plan

Why should this be in this repo and should it be part of the default EDOT distribution?
Asking to see how we put this here. Also depending on the answer you may need additional PRs in elastic agent.

We would like to run the verifier receiver in elastic-agent when configured via agent policy that has the verifier integration. This is similar to how filelog_otel behaves.
The difference is that the filelog_otel is based on filelogreceiver in open-telemetry that was delivered to open-telemetry and I understood that this repository allows us to implement Elastic receivers and include them in the agent (please correct me if I'm wrong), I didn't see any Elastic receivers imported from the fork repository.
The receiver will be part of the edot-base in the file that you've mentioned.
There is already an open PR in elastic-agent to include it.

what's when the collector doesn't run in any of those cloud environments? I see this'd print warnings when InitializeVerifier fails. Just wanna make sure this behaves properly in environments where this receiver has nothing to do - especially if this'd be by default part of EDOT. I looked a bit at receiver_test.go‎ and it's not clear to me that e.g. in a plain docker container (where from what I understand this receiver should't do anything), our EDOT collector would behave 100% the same with and without this receiver.

We import into the factory in elastic-agent:

The receiver will activate only when service.pipelines mentions it like this example for our integration:

The verifier receiver has no init functions, no state. If the config doesn't reference the verifier in any pipeline, those functions are never called. No receiver instance is created, no cloud SDKs are loaded, no env vars are read, no goroutines are spawned, no warnings are logged. This is the same guarantee that applies to every other receiver (like awss3receiver, k8sclusterreceiver...).

Add to registry, remove Okta, update docs, handle shutdown, update verifiers errors
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@versions.yaml`:
- Line 29: The new receiver module
"github.com/elastic/opentelemetry-collector-components/receiver/verifierreceiver"
was added to the excluded-modules list in versions.yaml which prevents it from
being shipped; remove that entry from the excluded-modules block (or move it to
the appropriate included-modules/release list) so "verifierreceiver" is part of
the edot-base release/version flow and available at runtime.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fbeee3c and 1c8036b.

📒 Files selected for processing (8)
  • receiver/verifierreceiver/README.md
  • receiver/verifierreceiver/doc.go
  • receiver/verifierreceiver/internal/verifier/aws_verifier.go
  • receiver/verifierreceiver/internal/verifier/gcp_verifier.go
  • receiver/verifierreceiver/receiver.go
  • receiver/verifierreceiver/receiver_test.go
  • receiver/verifierreceiver/registry.go
  • versions.yaml
✅ Files skipped from review due to trivial changes (1)
  • receiver/verifierreceiver/doc.go

Comment thread versions.yaml Outdated
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated by PR Review Agent for issue #1046

Comment on lines +367 to +370
// Provider credentials validation is handled by their respective Validate() methods
// which are called automatically by the OTel framework.

return nil
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚪ LOW] Nested credential Validate() methods are not invoked

The comment states that provider credential validation "is handled by their respective Validate() methods which are called automatically by the OTel framework," but as of component@v1.44.0, the framework only calls Validate() on the top-level Config struct — it does not recurse into nested structs. This means AWSCredentials.Validate(), AzureCredentials.Validate(), and OktaCredentials.Validate() are never called during config loading, so errors like "role_arn must be specified when external_id is set" would not be caught early.

The runtime impact is low since verifier initialization handles bad credentials gracefully (logs a warning and skips). Consider either calling them from Config.Validate() or updating the comment:

Suggested change
// Provider credentials validation is handled by their respective Validate() methods
// which are called automatically by the OTel framework.
return nil
// Provider credentials are validated at runtime during verifier initialization.
// Invalid credentials are reported as warnings and the affected provider is skipped.

@axw
Copy link
Copy Markdown
Member

axw commented Mar 2, 2026

@jeniawhite this is only for EDOT Collector, right? If so, it should go into the elastic-agent repo: https://github.com/elastic/elastic-agent/tree/main/internal/pkg/otel

CC @cmacknz in case you've discussed something different

@cmacknz
Copy link
Copy Markdown
Member

cmacknz commented Mar 2, 2026

Yes, it could go in elastic-agent instead unless they specifically want it to be Apache licensed. It'll be ELv2 in Elastic Agent.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generated by PR Review Agent for issue #1046

Comment on lines +126 to +132
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `tenant_id` | `string` | Yes* | Azure AD tenant ID |
| `client_id` | `string` | Yes* | Azure AD application client ID |
| `client_secret` | `string` | Yes* | Azure AD application secret |
| `subscription_id` | `string` | No | Azure subscription ID |
| `use_managed_identity` | `bool` | No | Use Azure Managed Identity |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚪ LOW] Azure credentials table documents fields that don't exist in the code

The table lists client_secret (line 130) and use_managed_identity (line 132), but the AzureCredentials struct in config.go has neither. The actual fields are tenant_id, client_id, subscription_id, and use_default_credentials. Users following these docs would configure client_secret and use_managed_identity, which would be silently ignored by mapstructure, leading to authentication failures.

The table should match the AzureCredentials struct:

Option Type Required Description
tenant_id string Yes* Azure AD tenant ID
client_id string Yes* Azure AD application client ID
subscription_id string No Azure subscription ID
use_default_credentials bool No Use DefaultAzureCredential (az login / env vars)

Comment on lines +136 to +141
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| `project_id` | `string` | No | GCP project ID |
| `service_account_key` | `string` | No | Service account JSON key |
| `use_default_credentials` | `bool` | No | Use application default credentials |
| `impersonate_service_account` | `string` | No | Service account to impersonate |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚪ LOW] GCP credentials table documents fields that don't exist in the code

The table lists service_account_key (line 139) and impersonate_service_account (line 141), but the GCPCredentials struct in config.go has workload_identity_provider, service_account_email, project_id, and use_default_credentials. Same as with Azure above — users following these docs would set options that are silently ignored.

The table should match the GCPCredentials struct:

Option Type Required Description
project_id string No GCP project ID
workload_identity_provider string No Full resource name of the GCP WIF provider
service_account_email string No GCP service account to impersonate via WIF
use_default_credentials bool No Use Application Default Credentials

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several YAML config files (testdata/config.yaml, testdata/agent-simulation.yaml) and the README examples use integration_id/integration_type/integration_name/integration_version field names, but the IntegrationConfig struct uses policy_template/package_name/package_policy_id/package_title/package_version. The mismatched configs will fail at validation because the required fields (policy_template, package_name) would be empty. The working test configs (test-aws.yaml, test-azure.yaml, test-gcp.yaml, test-standalone.yaml) already use the correct names.

Generated by PR Review Agent for issue #1046

Comment on lines +22 to +25
- integration_id: "int-cloudtrail-001"
integration_type: "aws_cloudtrail"
integration_name: "AWS CloudTrail"
integration_version: "2.17.0"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 HIGH] Integration fields use wrong YAML keys — config would fail validation

These YAML keys (integration_id, integration_type, integration_name, integration_version) don't match the IntegrationConfig struct's mapstructure tags. When deserialized, the actual fields (policy_template, package_name, package_policy_id, package_title, package_version) will all be empty strings, causing Validate() to fail with "policy_template must be specified".

Compare with testdata/test-aws.yaml which uses the correct field names.

Suggested change
- integration_id: "int-cloudtrail-001"
integration_type: "aws_cloudtrail"
integration_name: "AWS CloudTrail"
integration_version: "2.17.0"
- policy_template: "cloudtrail"
package_name: "aws"
package_title: "AWS CloudTrail"
package_version: "2.17.0"

The same issue applies to all other integration entries in this file (lines 29-35, 39-41, 63-65, 85-87).

Comment on lines +163 to +168
|--------|------|----------|-------------|
| `integration_id` | `string` | No | Unique identifier for the integration instance |
| `integration_type` | `string` | Yes | Package/integration type (e.g., `aws_cloudtrail`) |
| `integration_name` | `string` | No | Human-readable name of the integration |
| `integration_version` | `string` | No | Semantic version of the integration package (e.g., `2.17.0`). Different versions may require different permissions. When empty, the latest registered permission set is used. |
| `config` | `map[string]interface{}` | No | Provider-specific configuration |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 HIGH] IntegrationConfig table documents non-existent fields

This table doesn't match the actual IntegrationConfig struct in config.go. The struct uses Fleet API vocabulary:

Documented Field Actual mapstructure Tag
integration_id (no equivalent — use package_policy_id)
integration_type (derived from package_name + _ + policy_template)
integration_name (no equivalent — use package_title)
integration_version package_version

The table should document the actual fields: policy_template (required), package_name (required), package_policy_id, package_title, package_version, and config.

Comment on lines +239 to +243
| `integration.id` | Integration instance identifier |
| `integration.name` | Integration name |
| `integration.type` | Integration type (e.g., `aws_cloudtrail`) |
| `integration.version` | Integration package version (e.g., `2.17.0`) or `unspecified` |
| `provider.type` | Provider type (`aws`, `azure`, `gcp`, `okta`) |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟡 MEDIUM] Log Record Attributes table doesn't match emitted attributes

The actual code in receiver.go emits different attribute keys than documented here:

Documented Attribute Actually Emitted
integration.id package_policy.id
integration.name package.title
integration.type policy_template + package.name (separate attributes)
integration.version package.version

This table should be updated to reflect the actual attribute names emitted by emitPermissionCheckLog(). The same mismatch exists in testdata/expected-logs.yaml.

Comment on lines +30 to +33
- integration_id: "int-cloudtrail-001"
integration_type: "aws_cloudtrail"
integration_name: "AWS CloudTrail"
integration_version: "2.17.0"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 HIGH] Same broken field names as testdata/config.yaml

All integration entries in this file use the old naming convention (integration_id, integration_type, etc.) instead of the struct's actual fields (policy_template, package_name, package_policy_id, package_title, package_version). This config will fail validation at runtime.

Suggested change
- integration_id: "int-cloudtrail-001"
integration_type: "aws_cloudtrail"
integration_name: "AWS CloudTrail"
integration_version: "2.17.0"
- policy_template: "cloudtrail"
package_name: "aws"
package_title: "AWS CloudTrail"
package_version: "2.17.0"

Same fix needed for all other integration entries in this file.

Comment on lines +74 to +77
- integration_id: "int-cloudtrail-001"
integration_type: "aws_cloudtrail"
integration_name: "AWS CloudTrail"
integration_version: "2.17.0" # Version-aware permissions
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 HIGH] README YAML examples use wrong integration field names

The IntegrationConfig struct (in config.go) uses mapstructure tags: policy_template, package_name, package_policy_id, package_title, package_version. But this example uses integration_id, integration_type, integration_name, integration_version which are not recognized — users copying this would get a validation error.

Suggested change
- integration_id: "int-cloudtrail-001"
integration_type: "aws_cloudtrail"
integration_name: "AWS CloudTrail"
integration_version: "2.17.0" # Version-aware permissions
- policy_template: "cloudtrail"
package_name: "aws"
package_title: "AWS CloudTrail"
package_version: "2.17.0" # Version-aware permissions

The same fix is needed for all YAML example integration entries in this file (lines 82-84, 94-96, and the Example Pipeline section at lines 354-358).

jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 3, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.

Made-with: Cursor
@jeniawhite
Copy link
Copy Markdown
Author

Closing in favor of elastic/elastic-agent#13021 which moves the verifier receiver directly into elastic-agent, per feedback from @axw and @cmacknz that this receiver is EDOT Collector-only and should live in elastic-agent under ELv2.

@jeniawhite jeniawhite closed this Mar 3, 2026
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 4, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 4, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 17, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 24, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 24, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 27, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 27, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 27, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 27, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 30, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Mar 30, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Apr 3, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to jeniawhite/elastic-agent that referenced this pull request Apr 3, 2026
…stic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces elastic#12728.
jeniawhite added a commit to elastic/elastic-agent that referenced this pull request Apr 6, 2026
* Move verifier receiver from opentelemetry-collector-components to elastic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces #12728.

* CI fixes

* CI fixes

* Moving receiver to EDOT

* CI checks

* Verifier skill

* Rename datastream

* Enhance semver

* Verify policies and align auth

* CI fixes

* Move verifier receiver from opentelemetry-collector-components to elastic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces #12728.

* CI fixes

* Moving receiver to EDOT

* Rename datastream

* Enhance semver

* Verify policies and align auth

* CI fixes

* Addition test cases

* Remove skill

* fips compliance

* Curve gap and tests

* Rename CC

* Rebase

* GCP project id resolver

* Update go.mod

* Rebase fixes and documentation for AWS and Azure

* Delete beats

* Resolve submod

* fix: restore beats submodule pointer

* notice updates

* Use IRSA when available

* Remove NS and dataset

* Account string changes

* Audience rename

* Remove region

* Rewrite API calls and leave CSPM, Asset registry

* Update notice and format

* Move verifier receiver from opentelemetry-collector-components to elastic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces #12728.

* CI fixes

* CI fixes

* Moving receiver to EDOT

* CI checks

* Verifier skill

* Rename datastream

* Enhance semver

* Verify policies and align auth

* CI fixes

* Move verifier receiver from opentelemetry-collector-components to elastic-agent

Per review feedback on elastic/opentelemetry-collector-components#1046,
the verifier receiver is EDOT Collector-only and belongs in elastic-agent
(ELv2) rather than the shared Apache-licensed OTel components repo.

This moves the full verifier receiver implementation into
internal/pkg/otel/receivers/verifierreceiver/, updates import paths,
replaces Apache 2.0 license headers with ELv2, registers the receiver
in the EDOT component factory, and adds it to the all-components test
configs.

Replaces #12728.

* CI fixes

* Moving receiver to EDOT

* Rename datastream

* Enhance semver

* Verify policies and align auth

* CI fixes

* Addition test cases

* Remove skill

* fips compliance

* Curve gap and tests

* Rename CC

* Rebase

* GCP project id resolver

* Rebase fixes and documentation for AWS and Azure

* Delete beats

* Resolve submod

* fix: restore beats submodule pointer

* notice updates

* Use IRSA when available

* Remove NS and dataset

* Account string changes

* Audience rename

* Remove region

* Rewrite API calls and leave CSPM, Asset registry

* Update notice and format

* Create go.sum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants