Integrations
Cloud Provider Integrations
EchelonGraph connects to your cloud providers using read-only credentials. We never request write, delete, or modify permissions — our scanner operates entirely through API calls.
AWS Integration
What You Need
- An AWS account (with IAM admin permissions to create roles/policies)
- An EchelonGraph account with Admin role
- Your EchelonGraph Tenant ID (found in Settings → Organization)
Option A: Cross-Account IAM Role (Recommended)
This is the recommended production method. EchelonGraph uses AWS STS AssumeRole — no long-lived access keys are stored.
#### Step 1: Create the IAM Policy
This single read-only policy covers everything EchelonGraph scans in AWS: it lists every AWS action the scanner calls, and nothing it does not. It is split into four clearly-labeled blocks so you can see exactly what each capability needs:
EchelonGraphCore— infrastructure posture: EC2 and EBS, VPC, S3, RDS and Aurora, Lambda, ELB, EKS, ECS, AWS Batch, CodeBuild, Glue, App Runner, Step Functions, API Gateway, CloudFront, DynamoDB, EFS, SNS, SQS, Secrets Manager (secret metadata only, never values), Systems Manager documents, CloudWatch Logs, KMS, CloudTrail, ACM, Route 53, GuardDuty, AWS Config and IAM Access Analyzer. It also covers EC2 user-data secret scanning, andcloudtrail:LookupEvents, which our change monitor uses to pick up configuration changes between scans.EchelonGraphCIEM— Cloud Infrastructure Entitlement Management: reads IAM users, groups, roles, instance profiles, SAML and OIDC identity providers, and policy documents to detect privilege-escalation paths and over-privileged identities.iam:GetInstanceProfileis what connects an EC2 instance to the role it runs as; without it, no attack path can start from an instance, and the scan is marked degraded. The threeorganizations:reads collect the service control policies that apply to the account. AWS answers them only in an Organizations management account or a delegated administrator; anywhere else they are refused and the scan continues without SCP data.EchelonGraphAISPM— AI Security Posture Management: Amazon SageMaker notebook and Amazon Bedrock genAI posture.EchelonGraphContainerScan— pulls image manifests/layers from Amazon ECR for software-composition analysis (SCA), CVE and license detection, and reads repository metadata and policies.lambda:GetFunctionis here because it is how the scanner learns which image a container-packaged Lambda function runs; it is called only for image-packaged functions, and only the image fields of the response are read.
Every action is read-only (Describe, List, Get, BatchGet, LookupEvents, and API Gateway's GET). Create the policy with this JSON:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EchelonGraphCore",
"Effect": "Allow",
"Action": [
"access-analyzer:ListAnalyzers",
"acm:DescribeCertificate",
"acm:ListCertificates",
"apigateway:GET",
"apprunner:DescribeService",
"apprunner:ListServices",
"batch:DescribeComputeEnvironments",
"batch:DescribeJobDefinitions",
"cloudfront:GetDistributionConfig",
"cloudfront:ListDistributions",
"cloudtrail:DescribeTrails",
"cloudtrail:GetTrailStatus",
"cloudtrail:LookupEvents",
"codebuild:BatchGetProjects",
"codebuild:ListProjects",
"config:DescribeConfigurationRecorderStatus",
"dynamodb:GetResourcePolicy",
"dynamodb:ListTables",
"ec2:DescribeFlowLogs",
"ec2:DescribeImageAttribute",
"ec2:DescribeImages",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstances",
"ec2:DescribeInternetGateways",
"ec2:DescribeNatGateways",
"ec2:DescribeRegions",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSnapshots",
"ec2:DescribeSubnets",
"ec2:DescribeVolumes",
"ec2:DescribeVpcs",
"ec2:GetEbsEncryptionByDefault",
"ec2:GetImageBlockPublicAccessState",
"ec2:GetSnapshotBlockPublicAccessState",
"ecs:DescribeServices",
"ecs:DescribeTaskDefinition",
"ecs:ListClusters",
"ecs:ListServices",
"ecs:ListTaskDefinitions",
"eks:DescribeCluster",
"eks:ListClusters",
"eks:ListNodegroups",
"elasticfilesystem:DescribeFileSystemPolicy",
"elasticfilesystem:DescribeFileSystems",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeTargetGroups",
"glue:GetJobs",
"guardduty:GetDetector",
"guardduty:ListDetectors",
"guardduty:ListFindings",
"kms:DescribeKey",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:ListKeys",
"lambda:GetFunctionUrlConfig",
"lambda:GetPolicy",
"lambda:ListFunctions",
"logs:DescribeLogGroups",
"rds:DescribeDBClusterSnapshotAttributes",
"rds:DescribeDBClusterSnapshots",
"rds:DescribeDBClusters",
"rds:DescribeDBInstances",
"rds:DescribeDBSnapshotAttributes",
"rds:DescribeDBSnapshots",
"route53:ListHostedZones",
"s3:GetAccountPublicAccessBlock",
"s3:GetBucketAcl",
"s3:GetBucketLocation",
"s3:GetBucketLogging",
"s3:GetBucketNotification",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketOwnershipControls",
"s3:GetBucketPolicy",
"s3:GetBucketPolicyStatus",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetEncryptionConfiguration",
"s3:GetReplicationConfiguration",
"s3:ListAllMyBuckets",
"secretsmanager:ListSecrets",
"sns:GetTopicAttributes",
"sns:ListTopics",
"sqs:GetQueueAttributes",
"sqs:ListQueues",
"ssm:DescribeDocumentPermission",
"ssm:ListDocuments",
"states:DescribeStateMachine",
"states:ListStateMachines",
"sts:GetCallerIdentity"
],
"Resource": "*"
},
{
"Sid": "EchelonGraphCIEM",
"Effect": "Allow",
"Action": [
"iam:GetAccountPasswordPolicy",
"iam:GetAccountSummary",
"iam:GetGroup",
"iam:GetGroupPolicy",
"iam:GetInstanceProfile",
"iam:GetOpenIDConnectProvider",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:GetSAMLProvider",
"iam:GetUser",
"iam:GetUserPolicy",
"iam:ListAccessKeys",
"iam:ListAttachedGroupPolicies",
"iam:ListAttachedRolePolicies",
"iam:ListAttachedUserPolicies",
"iam:ListGroupPolicies",
"iam:ListGroups",
"iam:ListGroupsForUser",
"iam:ListMFADevices",
"iam:ListOpenIDConnectProviders",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:ListSAMLProviders",
"iam:ListUserPolicies",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"organizations:DescribePolicy",
"organizations:ListParents",
"organizations:ListPoliciesForTarget"
],
"Resource": "*"
},
{
"Sid": "EchelonGraphAISPM",
"Effect": "Allow",
"Action": [
"bedrock:GetModelInvocationLoggingConfiguration",
"bedrock:ListCustomModels",
"bedrock:ListGuardrails",
"sagemaker:DescribeNotebookInstance",
"sagemaker:ListNotebookInstances"
],
"Resource": "*"
},
{
"Sid": "EchelonGraphContainerScan",
"Effect": "Allow",
"Action": [
"ecr:BatchGetImage",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetAuthorizationToken",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"lambda:GetFunction"
],
"Resource": "*"
}
]
}> Prefer AWS-managed policies? SecurityAudit + ViewOnlyAccess cover the Core and CIEM blocks, but they do not include Amazon Bedrock reads (AI-SPM) or the container-scanning actions: the ECR image-pull actions (ecr:GetAuthorizationToken, ecr:BatchGetImage, ecr:GetDownloadUrlForLayer) and lambda:GetFunction. If you go the managed-policy route, also attach a small inline policy containing the EchelonGraphAISPM and EchelonGraphContainerScan statements above — otherwise those scans return nothing with no error.
#### Step 2: Create the IAM Role with Trust Policy
Create an IAM role with the following trust policy. Replace YOUR_TENANT_ID with your EchelonGraph tenant ID:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::781714039262:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "YOUR_TENANT_ID"
}
}
}
]
}#### AWS CLI Commands
# 1. Create the IAM policy
aws iam create-policy \
--policy-name EchelonGraphSecurityAudit \
--policy-document file://echelongraph-policy.json
# 2. Create the IAM role with the trust policy
aws iam create-role \
--role-name EchelonGraphSecurityAudit \
--assume-role-policy-document file://echelongraph-trust.json \
--description "Read-only role for EchelonGraph cloud security scanning"
# 3. Attach the policy to the role
aws iam attach-role-policy \
--role-name EchelonGraphSecurityAudit \
--policy-arn arn:aws:iam::YOUR_ACCOUNT_ID:policy/EchelonGraphSecurityAudit
# 4. (Alternative) Use the AWS-managed policies instead of the inline one.
# BOTH are required: the pair is what covers the Core and CIEM blocks. And
# neither covers Bedrock (AI-SPM) or the container-scanning actions (the
# ECR image pull and lambda:GetFunction), so the AISPM and ContainerScan
# statements above are still needed for those.
aws iam attach-role-policy \
--role-name EchelonGraphSecurityAudit \
--policy-arn arn:aws:iam::aws:policy/SecurityAudit
aws iam attach-role-policy \
--role-name EchelonGraphSecurityAudit \
--policy-arn arn:aws:iam::aws:policy/job-function/ViewOnlyAccess#### CloudFormation (1-Click Deploy)
Deploy this CloudFormation template in your AWS Console to create the role automatically:
AWSTemplateFormatVersion: '2010-09-09'
Description: EchelonGraph Security Audit - Cross-Account IAM Role
Parameters:
TenantId:
Type: String
Description: Your EchelonGraph Tenant ID (found in Settings)
MinLength: 1
Resources:
EchelonGraphRole:
Type: AWS::IAM::Role
Properties:
RoleName: EchelonGraphSecurityAudit
Description: Read-only role for EchelonGraph cloud security scanning
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: 'arn:aws:iam::781714039262:root'
Action: 'sts:AssumeRole'
Condition:
StringEquals:
'sts:ExternalId': !Ref TenantId
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/SecurityAudit'
- 'arn:aws:iam::aws:policy/job-function/ViewOnlyAccess'
Outputs:
RoleArn:
Description: Role ARN to paste into EchelonGraph
Value: !GetAtt EchelonGraphRole.Arn#### Step 3: Connect in EchelonGraph
- Go to Settings → Cloud Accounts → Add Account
- Select Amazon Web Services
- Choose Cross-Account Role (Recommended)
- Paste your Role ARN (e.g.
arn:aws:iam::123456789012:role/EchelonGraphSecurityAudit) - The External ID field is auto-populated with your EchelonGraph Tenant ID — no action needed
- Select your primary AWS region
- Click Test Connection — EchelonGraph will validate access via STS
- Save and trigger your first scan
Option B: Access Keys (Quick Start)
For rapid evaluation, you can use IAM user access keys. Not recommended for production — use cross-account roles instead.
- Create an IAM user with the same read-only permissions the role path needs: the
SecurityAuditandViewOnlyAccessmanaged policies, plus the inline policy from Option A. AttachingSecurityAuditalone leaves AI-SPM and container scanning with no permissions, and those scans then return nothing with no error - Generate an access key pair in IAM → Users → Security Credentials
- Go to Settings → Cloud Accounts → Add Account
- Select Amazon Web Services → Access Keys (Quick Start)
- Enter your Access Key ID and Secret Access Key
- Select your primary region and click Test Connection
> Security note: Access keys are long-lived credentials. If you use this method, rotate keys every 90 days and restrict the IAM user to exactly the read-only permissions in step 1 — no more, and no less: a user granted less than that scans partially and reports success.
What EchelonGraph Scans (17 AWS Services + CIEM)
| Service | Assets Discovered | API Calls Used |
|---|---|---|
| EC2 | Instances, AMIs, security groups | DescribeInstances |
| VPC | VPCs, subnets, NAT/Internet gateways | DescribeVpcs, DescribeSubnets, DescribeNatGateways, DescribeInternetGateways |
| Security Groups | Ingress/egress rules, CIDR ranges | DescribeSecurityGroups |
| RDS | Database instances, encryption, backups | DescribeDBInstances |
| S3 | Buckets — encryption, versioning, public access, ACLs | ListBuckets, GetBucketEncryption, GetBucketAcl, GetPublicAccessBlock, GetBucketVersioning, GetBucketLocation |
| IAM + CIEM | Users, roles, MFA, key age, and policy documents — privilege-escalation paths, over-privilege, wildcard actions, risky PassRole | ListUsers, ListRoles, GetPolicy, GetPolicyVersion, GetRolePolicy, ListAttachedRolePolicies |
| Lambda | Functions — runtime, VPC config, layers, env vars | ListFunctions |
| ELB/ALB | Load balancers, listeners, target groups, certificates | DescribeLoadBalancers, DescribeListeners, DescribeTargetGroups |
| CloudTrail | Trails, logging status, multi-region config | DescribeTrails, GetTrailStatus |
| ACM | TLS certificates — expiry, renewal status | ListCertificates, DescribeCertificate |
| KMS | Encryption keys — rotation status, key policies | ListKeys, DescribeKey, GetKeyRotationStatus |
| Route 53 | Hosted zones, DNS records | ListHostedZones, ListResourceRecordSets |
| EKS | Kubernetes clusters — version, endpoints, logging | ListClusters, DescribeCluster |
| GuardDuty | Threat detections — severity, findings | ListDetectors, ListFindings, GetFindings |
All calls are read-only. EchelonGraph never modifies, creates, or deletes any AWS resource.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
AccessDenied on AssumeRole | Trust policy doesn't match | Verify the Principal ARN and ExternalId in your trust policy |
ExpiredToken | STS session expired | EchelonGraph automatically refreshes — retry the scan |
UnauthorizedAccess on a specific API | Missing permission | Add the API action to your IAM policy |
| Connection test succeeds but scan returns 0 assets | Wrong region selected | Ensure the region in EchelonGraph matches where your resources are deployed |
InvalidIdentityToken | Incorrect role ARN format | Role ARN must be arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME |
Credential Rotation
- Cross-Account Role: No rotation needed — STS tokens are short-lived (1 hour). Update the trust policy only if you change your EchelonGraph tenant ID.
- Access Keys: Rotate every 90 days via IAM → Users → Security Credentials. Update the new keys in EchelonGraph Settings → Cloud Accounts.
EchelonGraph uses AWS STS AssumeRole — no long-lived access keys are required.
GCP Integration
What You Need
- A GCP project (the one you want to scan)
- An EchelonGraph account with Admin role
- Permission to create a service account and grant project IAM roles (
roles/resourcemanager.projectIamAdminor Owner)
EchelonGraph connects with read-only access only — we never request write, delete, or modify permissions.
Step 1: Enable the required APIs
EchelonGraph reads through Google Cloud APIs. Enable them once per project:
gcloud services enable \
cloudasset.googleapis.com \
cloudresourcemanager.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
container.googleapis.com \
sqladmin.googleapis.com \
storage.googleapis.com \
secretmanager.googleapis.com \
artifactregistry.googleapis.com \
run.googleapis.com \
dns.googleapis.com \
cloudkms.googleapis.com \
--project=YOUR_PROJECT_ID> If an API is left disabled, EchelonGraph simply skips that scanner (no error) — so enabling all of the above is what gives you a complete first scan.
Step 2: Grant the four read-only roles
These predefined roles cover every EchelonGraph scanner — all strictly read-only:
| Role | What it powers |
|---|---|
roles/viewer | Core posture — Compute, VPC/firewall, Cloud SQL, Cloud Storage, GKE, Cloud Run, Cloud Functions, KMS, DNS, Secret Manager (metadata only) |
roles/iam.securityReviewer | CIEM — reads the project IAM policy + custom-role definitions to detect privilege escalation and over-privilege |
roles/artifactregistry.reader | Container scanning (SCA) — pulls image manifests/layers from Artifact Registry for CVE + license analysis |
roles/cloudasset.viewer | Cloud Asset Inventory — powers near-real-time change detection and complete resource discovery |
> Why securityReviewer? GCP's basic roles/viewer cannot read IAM policy bindings or custom roles. CIEM needs resourcemanager.projects.getIamPolicy + iam.roles.list, which roles/iam.securityReviewer grants — and only for reading.
Option A: Workload Identity Federation (Recommended — zero secrets)
With WIF, no service-account key is ever created, stored, or transmitted — EchelonGraph exchanges a short-lived federated token. This is the most secure model.
# 1. Create the service account (no key)
gcloud iam service-accounts create echelongraph-scanner \
--display-name="EchelonGraph read-only scanner" \
--project=YOUR_PROJECT_ID
# 2. Grant the four read-only roles
SA="echelongraph-scanner@YOUR_PROJECT_ID.iam.gserviceaccount.com"
for ROLE in roles/viewer roles/iam.securityReviewer roles/artifactregistry.reader roles/cloudasset.viewer; do
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \
--member="serviceAccount:$SA" --role="$ROLE"
doneThen in EchelonGraph go to Settings → Cloud Accounts → Add Account → Google Cloud, choose Workload Identity Federation, paste the service-account email and project ID, and follow the on-screen steps to authorize the EchelonGraph workload pool.
Option B: Service-Account Key (Quick Start)
For rapid evaluation. Not recommended for production — the key is a long-lived credential.
# After creating the SA + granting the four roles (Option A, steps 1–2):
gcloud iam service-accounts keys create echelongraph-key.json \
--iam-account="$SA"In EchelonGraph go to Settings → Cloud Accounts → Add Account → Google Cloud, choose Service-Account Key, upload echelongraph-key.json, enter your project ID, click Test Connection, then trigger your first scan.
> Security note: rotate service-account keys every 90 days — or use Workload Identity Federation (Option A) to avoid keys entirely.
What EchelonGraph Scans (GCP)
| Service | Assets & Checks |
|---|---|
| Compute Engine | VMs — public IP, OS Login, Shielded VM, SA scopes |
| VPC / Firewall | Networks, subnets, firewall rules (0.0.0.0/0 exposure) |
| Cloud SQL | Instances — public IP, SSL, backups, encryption |
| Cloud Storage | Buckets — public access, uniform access, encryption |
| GKE | Clusters — version, private nodes, Workload Identity, logging |
| Cloud Run | Services — ingress, unauthenticated invokers |
| Secret Manager | Secrets (metadata only — never values) — rotation, expiry |
| Artifact Registry | Container images — CVEs, OS/library vulns, licenses (SCA) |
| IAM + CIEM | Project IAM bindings + custom roles — primitive Owner/Editor, SA impersonation, setIamPolicy, actAs, key-admin privilege escalation |
| KMS / DNS / Cloud Armor | Key rotation, DNSSEC, WAF policies |
All access is read-only. EchelonGraph never modifies, creates, or deletes any GCP resource.
Azure Integration
What You Need
- An Azure AD App Registration with
Readerrole on your target subscriptions - *(Optional, for container-image scanning)* the
AcrPullrole on any Azure Container Registries you want scanned
Setup
- Create an App Registration and Service Principal in Azure AD
- Assign the Reader role on the subscriptions you want to scan
- *(Optional)* Assign
AcrPullon your container registries to enable ACR image scanning (see note below) - Register the cloud account in EchelonGraph, providing the tenant ID, client ID, client secret, and subscription ID
> The built-in Reader role grants */read, which covers everything EchelonGraph needs for CIEM (RBAC role assignments + custom-role definitions via Azure Resource Graph) and AI-SPM (Azure ML workspaces, Azure OpenAI / Cognitive Services) — no extra permissions required there. > > Container-image (ACR) scanning — Preview. Enumerating images in your Azure Container Registries and pulling them for SCA reads the ACR data plane (the _catalog / _tags APIs and image layers), which the control-plane Reader role does not grant. Assign the built-in AcrPull role on the registries you want scanned. EchelonGraph authenticates with your App Registration via the standard AAD→ACR token exchange — strictly read-only (catalog + metadata_read + pull), never push or delete. Shipped + unit-tested; live-environment validation is in progress, so ACR scanning is labeled Preview.
SSO — SAML 2.0
Connect your SAML 2.0 identity provider for single sign-on. Supported IdPs include Okta, Azure AD, OneLogin, and PingIdentity.
Setup
- Create a SAML application in your IdP with the EchelonGraph ACS URL and audience URI (provided in your admin console)
- Configure the integration in EchelonGraph with your IdP metadata URL
- Enable automatic user provisioning and set a default role for new SSO users
SSO — OIDC
Connect any OpenID Connect provider for single sign-on. Supported providers include Google Workspace, Okta, Azure AD, Auth0, and Keycloak.
Setup
- Create an OIDC client in your IdP with the EchelonGraph callback URL (provided in your admin console)
- Configure the integration in EchelonGraph with your issuer URL, client ID, and client secret
- Enable automatic user provisioning and group-to-role mapping
Uses PKCE (RFC 7636) for secure authorization code flow.
SSO — LDAP / Active Directory
Connect your corporate directory for centralized authentication. Supports LDAPS (TLS) and StartTLS for encrypted connections.
Setup
- Configure the LDAP connection in EchelonGraph with your directory server details
- Define user and group search bases for automatic discovery
- Map LDAP groups to EchelonGraph roles for automatic role assignment
- Test the connection before enabling for users
Webhook Integrations
Send real-time security events to Slack, PagerDuty, Jira, ServiceNow, or any HTTP endpoint:
- Alert creation
- Scan completions
- Compliance score changes
- New finding detected
All webhook payloads are cryptographically signed for verification, ensuring you can trust the source of every notification.