4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
69 lines
2.9 KiB
Python
69 lines
2.9 KiB
Python
"""Shared AWS CloudTrail integration helpers.
|
|
|
|
CloudTrail is the canonical AWS change-causality source — "who changed what,
|
|
and when?". Unlike RDS, CloudTrail is account-wide rather than tied to a single
|
|
configured resource, so the CloudTrail tool rides on the account-level ``aws``
|
|
integration (``AWSIntegrationConfig``) for availability and region rather than
|
|
defining its own credential plumbing.
|
|
|
|
All AWS API calls are read-only and routed through the shared
|
|
``aws_sdk_client`` allowlist (``lookup_events`` matches ``^lookup_.*``), so the
|
|
integration cannot mutate any resources.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from integrations._relational import env_str
|
|
|
|
DEFAULT_CLOUDTRAIL_REGION = "us-east-1"
|
|
|
|
|
|
def cloudtrail_is_available(sources: dict[str, dict]) -> bool:
|
|
"""Check whether CloudTrail can be queried for this investigation.
|
|
|
|
CloudTrail forensics only needs AWS account access (credentials + region),
|
|
which the account-level ``aws`` integration already provides. We therefore
|
|
gate availability on the ``aws`` source the catalog populates from
|
|
``AWSIntegrationConfig`` — mirroring how the other AWS tools reuse the creds
|
|
wired via the EKS/CloudWatch path — and on the optional synthetic
|
|
``ec2_backend`` handle (the key the synthetic harness injects into the
|
|
``aws`` source) so the tool stays selectable in fixture-driven tests.
|
|
|
|
Note: ``role_arn`` / ``credentials`` here gate *availability* only. The
|
|
actual lookup runs through ``execute_aws_sdk_call``, which uses boto3's
|
|
ambient credential chain (env / shared config / instance role) — the
|
|
configured role is not assumed as the execution identity. This matches the
|
|
other AWS tools (RDS/EKS).
|
|
"""
|
|
aws = sources.get("aws", {})
|
|
return bool(
|
|
aws.get("connection_verified")
|
|
or aws.get("role_arn")
|
|
or aws.get("credentials")
|
|
or aws.get("ec2_backend")
|
|
)
|
|
|
|
|
|
def cloudtrail_extract_params(sources: dict[str, dict]) -> dict[str, Any]:
|
|
"""Extract CloudTrail call params (region) from the ``aws`` source.
|
|
|
|
Resolution order for region matches the rest of the AWS stack: explicit
|
|
``aws`` source field, then ``AWS_REGION`` env, then the default. Forwards
|
|
the optional synthetic ``ec2_backend`` handle (the key the synthetic harness
|
|
injects into the ``aws`` source) as ``aws_backend`` so the tool short-circuits
|
|
to fixture data instead of leaking boto3 calls to whatever AWS account the
|
|
developer happens to be authenticated against during a synthetic run.
|
|
Resource/principal/time-window filters are alert-specific and are supplied
|
|
by the planner at call time, not extracted here.
|
|
"""
|
|
aws = sources.get("aws", {})
|
|
region = (
|
|
str(aws.get("region") or "").strip() or env_str("AWS_REGION") or DEFAULT_CLOUDTRAIL_REGION
|
|
)
|
|
return {
|
|
"region": region,
|
|
"aws_backend": aws.get("ec2_backend"),
|
|
}
|