Permissions requested
Per cloud, the read permissions Ctadel asks for, the optional write permissions used to copy disks and databases, and what the scanner creates then removes in your account.
This page lists, cloud by cloud, what the identity you hand to Ctadel can do in your account: first the read access, which is enough for the inventory and the rules, then the optional write permissions used only to copy a disk or a database and read its content.
Two levels of permissions
Access to your accounts goes through the cloud APIs. It is not "read-only" as a whole: the inventory only reads, but the content analyses create resources in your account. Two levels must therefore be told apart: read permissions for the inventory and the configuration, plus disk-copy and database-copy permissions for the content analyses.
With the read permissions alone, Ctadel produces the inventory, the posture of accounts, buckets, databases and clusters (CSPM, KSPM, AI-SPM), identities and their permissions (CIEM), toxic combinations and attack paths.
Three analyses read content and need more:
| Analysis | What it reads | Extra permissions |
|---|---|---|
| Bucket content | The objects, in place, for secrets and sensitive data | Object read (no write) |
| Machine disks (Vulnerabilities, Secrets, Data and HCR on disks) | A copy of the volume, mounted in an ephemeral machine created in your account | Create and delete snapshots, volumes, machines, keys and security groups: write permissions |
| Databases | A temporary copy of the instance, read then deleted | Create and delete an instance and a user on the copy: write permissions |
Each one can be turned off without affecting the rest. The content of a disk or a database never leaves your account: only findings are sent back to your instance.
Read access per cloud
| Cloud | Identity | Read permissions |
|---|---|---|
| AWS | A role Ctadel assumes with an ExternalId, or an access key | SecurityAudit, ViewOnlyAccess and a list of extra actions (see below) |
| Azure | A service principal | Reader and Log Analytics Reader on the subscription; read-only Microsoft Graph application permissions |
| Google Cloud | A service account key, or a keyless external_account federation | roles/viewer, roles/iam.securityReviewer, roles/browser and targeted read roles |
| Scaleway | An IAM application | AllProductsReadOnly, IAMReadOnly, OrganizationReadOnly |
| OVHcloud | An API application and a Consumer Key | The listed GET routes, plus POST .../openstack/token and POST .../kube/*/kubeconfig |
| OUTSCALE | An EIM user with an expiring access key | api:Read* and the configuration reads of OOS buckets |
AWS
The recommended mode is a role created in your account by the CloudFormation template Ctadel provides: no long-lived key leaves your perimeter, and deleting the CloudFormation stack revokes access. The role can be assumed only by the principal of your Ctadel instance and with the ExternalId you generate in the application. Ctadel requests a 12-hour session (MaxSessionSeconds, 3,600 to 43,200 seconds) and falls back to one hour if the role forbids it.
The role carries the managed policies SecurityAudit and ViewOnlyAccess, plus a CtadelReadExtras policy that adds: iam:GenerateCredentialReport, iam:GetCredentialReport, shield:DescribeSubscription, shield:ListProtections, elasticloadbalancing:DescribeSSLPolicies, lambda:GetFunction, lambda:GetFunctionConfiguration, ecr:GetRepositoryPolicy, elasticfilesystem:DescribeFileSystemPolicy, eks:ListAccessEntries, eks:DescribeAccessEntry, eks:ListAssociatedAccessPolicies, ec2:DescribeTransitGatewayAttachments, ec2:GetSnapshotBlockPublicAccessState, ec2:GetImageBlockPublicAccessState, redshift-serverless:ListNamespaces, redshift-serverless:ListWorkgroups, appsync:GetApiCache, wafv2:GetWebACLForResource, cloudwatch:GetMetricData, route53resolver:ListResolverQueryLogConfigAssociations, the bedrock:*, bedrock-agentcore:* and sagemaker:* reads of the AI inventory, and iam:ListServiceSpecificCredentials. lambda:GetFunction returns a download URL for the function code, which is analysed for secrets, sensitive data and vulnerable packages.
The template options, all true by default except EnableSSMTransport, which is false:
| Parameter | Permissions added | Without it |
|---|---|---|
EnableBucketScanning | s3:GetObject, s3:GetObjectVersion, kms:Decrypt restricted to the S3 service | Bucket posture kept, content not read |
EnableDiskScanning | CtadelDiskScanning policy (see below) | Nothing on machine disks |
EnableDatabaseScanning | CtadelDatabaseScanning policy (see below) | Database posture kept, content not read |
EnableKubernetesAccess | eks:CreateAccessEntry, eks:DescribeAccessEntry, eks:AssociateAccessPolicy | You create the cluster access entry yourself |
EnableRuntimeEvents | sqs:ReceiveMessage, sqs:DeleteMessage, sqs:GetQueueAttributes, sqs:GetQueueUrl | CloudTrail read at each scan with cloudtrail:LookupEvents |
EnableSSMTransport | iam:PassRole on a dedicated instance role, ssm:SendCommand restricted to the AWS-RunShellScript document and to instances tagged ctadel-managed, read of command results | The scanner is reached over SSH |
With an access key instead of the role, attach SecurityAudit and ViewOnlyAccess to an IAM user; the secret is then stored encrypted in your instance, see Data and encryption.
Azure
On the subscription: Reader (ARM inventory, role assignments, activity log) and Log Analytics Reader. For blob content: Storage Blob Data Reader; Ctadel obtains an Entra token for https://storage.azure.com/ and never calls listKeys, which would hand out a read-write account key. For Azure Functions: a custom role with Microsoft.Web/sites/config/list/action and Microsoft.Web/sites/publish/action, and AcrPull on the registry of containerised functions; without them the function is reported as not read.
For AKS clusters, Ctadel obtains the kubeconfig through listClusterAdminCredential, an action that Reader does not include: it requires the "Azure Kubernetes Service Cluster Admin Role" on the cluster, and the kubeconfig obtained is an administrator kubeconfig. Without that role, the AKS posture read through ARM remains, but the cluster objects are not read.
Microsoft Graph application permissions, with admin consent: Application.Read.All, Directory.Read.All, User.Read.All, Policy.Read.All, AccessReview.Read.All, AuditLog.Read.All, Reports.Read.All. A missing permission leaves the matching property unknown, never "compliant".
Google Cloud
At the organisation level, or the project level in single-project mode: roles/viewer, roles/iam.securityReviewer, roles/browser. Specific rules need roles/accessapproval.viewer, roles/policyanalyzer.activityAnalysisViewer, roles/monitoring.viewer, roles/logging.viewer and roles/serviceusage.serviceUsageViewer. The credentials file can be an external_account (identity federation) that contains no private key.
Scaleway
An IAM application whose policy carries AllProductsReadOnly, IAMReadOnly and OrganizationReadOnly, at the organisation level.
OVHcloud
An API application on eu.api.ovh.com and a Consumer Key with no expiry date, limited to the GET routes of /me, /me/api/*, /me/identity/user*, /iam/policy*, /cloud/project/{projectId}*, /dedicated/server* and /domain/zone*, plus POST /cloud/project/{projectId}/openstack/token and POST /cloud/project/{projectId}/kube/*/kubeconfig. API keys do not read objects: bucket content requires an Object Storage user of the project and its S3 credentials, which are optional.
OUTSCALE
An EIM user without console access, a policy created from the read-only policy document Ctadel provides (api:Read* and seven OOS configuration reads) and an access key with an expiry date. The API is regional: one account entry per region.
Write access: copying disks
For each analysed volume, the disk scanner creates in your account a snapshot, a volume restored from that snapshot, then an ephemeral machine to which it attaches that volume; it reads the copy, then releases all three in reverse order. The release happens on success, on failure of any step, on cancellation and on an unexpected stop of the scan.
| Cloud | Write permissions | What is created, where | Marking |
|---|---|---|---|
| AWS | ec2:CreateSnapshot, CreateVolume, ImportKeyPair, CreateSecurityGroup, AuthorizeSecurityGroupIngress, RunInstances, AttachVolume; CreateTags only during those creations; TerminateInstances, DetachVolume, DeleteVolume, DeleteSnapshot, DeleteKeyPair, DeleteSecurityGroup only on resources tagged ctadel-managed=true | Snapshot, volume, key pair, security group and instance in the region and zone of the source volume | Name=ctadel-scanner-ephemeral, ctadel-managed=true |
| Azure | Creation of snapshot, disk, network security group, public address, network interface and virtual machine, and creation of a ctadel-scan-<region> resource group with its virtual network | Everything in the ctadel-scan-<region> resource group of your subscription | ctadel-managed=true |
| Google Cloud | Snapshot, disk, firewall rule and instance | In the project of the source disk | Label ctadel-managed=true, network tag ctadel-scanner, rule ctadel-ssh-* |
| Scaleway | Snapshot (Block or Instance API), volume, security group and server | In the project of the connected account | Tags ctadel-scanner and ephemeral, volume ctadel-temp-sbs-*, snapshot ctadel-scan-snap-* |
| OVHcloud | POST .../volume/*/snapshot, DELETE .../volume/snapshot/*, POST .../volume/*/attach, POST .../volume/*/detach, DELETE .../volume/*, POST .../instance, DELETE .../instance/* | In the connected Public Cloud project | Names ctadel-snap-*, ctadel-vol-*, ctadel-scanner-* |
| OUTSCALE | api:CreateSnapshot, CreateVolume, LinkVolume, UnlinkVolume, CreateVms, DeleteVms, CreateKeypair, DeleteKeypair, CreateSecurityGroup, CreateSecurityGroupRule, DeleteSecurityGroup, CreatePublicIp, LinkPublicIp, UnlinkPublicIp, DeletePublicIp, DeleteVolume, DeleteSnapshot, CreateTags | In the subregion of the source volume | Name=ctadel-scanner-ephemeral, ctadel-managed=true, key and group ctadel-scanner-* |
On AWS, the template conditions ec2:CreateTags on the creation action in progress: the role cannot tag one of your existing resources to make it deletable, and deletions apply only to what was created with the tag.
Write access: copying databases
Only PostgreSQL databases are read; other engines are refused before any copy, and an Aurora cluster is not supported. The database scanner creates the copy, creates a read account on it, runs the analysis then removes the copy, whatever the outcome of the analysis.
| Cloud | Write permissions | What is created | Cleanup |
|---|---|---|---|
| AWS | rds:CreateDBSnapshot, RestoreDBInstanceFromDBSnapshot, ModifyDBInstance, AddTagsToResource; DeleteDBInstance and DeleteDBSnapshot only on resources tagged ctadel-managed=true | A snapshot, then a db.t3.micro instance restored in the source's subnet group, a temporary security group that accepts only the egress address of your Ctadel instance; the master password is reset on the copy only | Instance deleted without a final snapshot, snapshot deleted, security group deleted |
| Google Cloud | Clone through the Cloud SQL Admin API, user creation, deletion | A ctadel-dspm-<timestamp> instance in the source's project | Instance deleted |
| Scaleway | RDB clone, user creation, deletion | A ctadel-dspm-clone-<timestamp> instance of type DB-PLAY2-PICO | Instance deleted |
| Azure, OVHcloud, OUTSCALE | None | Managed databases of these clouds are not copied | Not applicable |
The ephemeral scanner
- Content stays with you. The ephemeral machine reads the disk copy inside your account; only findings are sent back.
- One port, one source. The security group, NSG or firewall rule opens only port 22, and only from the egress address of your Ctadel instance (fixed when the instance is configured, otherwise discovered automatically). Without a usable range, the scan fails rather than opening the port.
- Keys per scan. The scanner generates for each scan the login key and the SSH host key of the machine, passes them through user data, and refuses any other host key. On OVHcloud, no key is registered through the API.
- Without a public address. Per account, in "Settings", "Integrations", "Cloud Providers", the "Disk scanner network (optional)" section pins a subnet and removes the public address (AWS, OUTSCALE, Google Cloud); this assumes a private path between your instance and that network. On AWS, the SSM transport removes every inbound rule and every address.
- Orphan sweep. At most once an hour per account, Ctadel deletes scan resources older than two hours that carry its tags or names, so that a hard stop leaves nothing billed.
Limits
- Kubernetes access on AWS. With
EnableKubernetesAccessset totrue, Ctadel creates an EKS access entry for the role and associates theAmazonEKSClusterAdminPolicypolicy with it, that is cluster administration rights, where read access would be enough. To grant read access only, set the parameter tofalseand create the access entry yourself, see Connect Kubernetes. - Kubernetes access on Azure. The AKS kubeconfig is requested through
listClusterAdminCredential: the role granted gives cluster administration, not read access only. Ctadel does not uselistClusterUserCredential. To grant read access only, register a restricted kubeconfig for that cluster yourself in "Integrations", "Kubernetes": a supplied kubeconfig takes precedence over the cloud credentials, see Connect Kubernetes. - Database copy on AWS. The temporary security group of the copy is created with
ec2:*actions that sit in the disk-copy policy, not in the database policy: withEnableDiskScanningset tofalseandEnableDatabaseScanningset totrue, the database copy fails. - Scope of write permissions outside AWS. On Azure, Google Cloud, Scaleway and OVHcloud, Ctadel names the write permissions without providing a template that restricts them by tag: limiting them to tagged resources only rests on your IAM configuration. Resources are created in the analysed subscription, project or account, not in a separate space.
- Undocumented permissions. Cloud SQL cloning and RDB cloning need write permissions on those services that the onboarding documentation does not list yet; ask Ctadel for them during setup. On Azure, creating the
ctadel-scan-<region>resource group and its virtual network needs more thanDisk Snapshot Contributor. - OUTSCALE buckets. The provided policy contains neither
oos:ListBucketnoroos:GetObject: without adding them, the content of OOS buckets is not read. - Internet egress of the scanner. At first boot, the ephemeral machine installs its analysis tools from public repositories: it needs outbound Internet access. Without it, the inventory of vulnerable packages is empty.
- Orphaned database copies. There is no sweep of database copies left by a hard stop, unlike disk resources.
- Public address of the AWS database copy. The copy is publicly accessible or not according to an instance-wide setting fixed by Ctadel, not the per-account setting.
- Runtime events. The
EnableRuntimeEventspermissions and the audit-log read roles are requested by the templates, but detection on those logs is in internal validation, not available to customers.