Every cloud security tool we looked at before we started building Native Security shared a structural assumption: the cloud isn't secure enough, so you need to deploy something into it that makes it more secure. An agent on each EC2 instance. A sidecar in each pod. A Lambda that runs on every CloudTrail event. Something that lives in your account, reads your data, and acts on your behalf.
We spent about two months working through whether that assumption was correct. Our conclusion: for the specific problem we're solving — enforcing the org-level controls your cloud provider already defined — it isn't. Adding an enforcement layer to a cloud account that already has an enforcement layer is architectural duplication, and it brings its own problems.
The Problem with Agents in a Cloud That Already Has Policy Enforcement
AWS SCPs, Azure Policies, and GCP Org Constraints are enforcement mechanisms that operate at the control plane level. They evaluate against API calls before those calls are processed by the service. They don't require anything installed in your account. They're not bounded by what a Lambda function can observe — they see every API call that reaches the IAM evaluation layer.
When you deploy an agent-based security tool into this environment, you're adding a second enforcement layer that operates on a different surface with different coverage. The agent sees what it can reach from inside the account. The native controls see everything at the API level. These aren't the same surface, and they don't compose cleanly.
More specifically, when you have two enforcement layers and a security incident happens, you get a question that's genuinely hard to answer: did the native control fail, or did the agent fail, or did both fail, or did the agent actually suppress something the native control would have caught? The interaction between agent-based enforcement and native policy enforcement is complex enough that teams often can't determine post-incident which layer was authoritative.
We're not saying agent-based security tools are wrong for all use cases. There are things agents do that native controls can't — runtime process monitoring, memory analysis, network packet inspection within an instance. Those are real capabilities that require in-instance instrumentation. But for the specific problem of enforcing org-level policy controls? An agent isn't the right abstraction.
What Read-Only Access Actually Means
Native Security connects to your cloud accounts with read-only access. Specifically:
For AWS, we use a cross-account IAM role with a policy that allows only organizations:Describe*, organizations:List*, iam:GetPolicy, iam:GetPolicyVersion, iam:ListPolicies, cloudtrail:LookupEvents, and similar read-only actions. No write permissions. No ability to attach, modify, or delete policies. No data plane access.
For Azure, we use an App Registration with the Reader role at the management group scope — sufficient to read policy definitions, assignments, and the management group hierarchy. Not Contributor, not Owner, not any role that can write resources.
For GCP, we use a Service Account with the roles/viewer and roles/orgpolicy.policyViewer predefined roles at the organization level.
The constraint is: we can see everything but touch nothing. The read-only boundary is what makes our architecture credible when we tell a security team "Native Security cannot be used to attack your cloud." A compromised Native Security credential can read your policy inventory. It cannot change anything in your account.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "NativeSecurityReadOnly",
"Effect": "Allow",
"Action": [
"organizations:DescribeOrganization",
"organizations:DescribeOrganizationalUnit",
"organizations:DescribePolicy",
"organizations:ListAccounts",
"organizations:ListAccountsForParent",
"organizations:ListOrganizationalUnitsForParent",
"organizations:ListPolicies",
"organizations:ListPoliciesForTarget",
"organizations:ListRoots",
"organizations:ListTargetsForPolicy",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:ListPolicies",
"iam:ListPolicyVersions",
"cloudtrail:GetTrailStatus",
"cloudtrail:ListTrails"
],
"Resource": "*"
}
]
}
This is the actual policy we ask teams to use when they connect AWS. No wildcards on the Action field. No resource wildcards beyond what's required for cross-account org API calls.
Where Native Security Sits in the Enforcement Chain
Our product doesn't enforce anything at runtime. The enforcement happens in your CI/CD pipeline, before the deployment reaches the cloud. We evaluate whether a proposed infrastructure change would violate an active SCP or org policy — and we block the deployment if it would.
The CI/CD gate reads the current state of your org's native controls (via our read-only connection), evaluates the proposed Terraform plan or CloudFormation template against those controls, and returns a pass/fail result. If it fails, the deployment stops. No agent required. The native controls are still the authoritative enforcement mechanism — we're just running their evaluation logic earlier in the pipeline, where a developer can act on the result.
This means we're not an alternative to your SCPs. We're a way to make your SCPs effective earlier. The SCP still fires at the IAM layer if someone bypasses the CI/CD pipeline. Our gate fires at the plan layer, before any AWS API is called. Both layers exist and both are necessary — we just add the earlier gate.
The Operational Arguments Against Agents
Beyond the architectural argument, there are operational reasons we wanted to avoid agent deployment:
Agent lifecycle management is a real engineering burden. Every agent you deploy is a thing that has to be updated, monitored for health, and replaced when it fails. In a multi-account AWS org with 30+ accounts, an agent-based tool means 30+ deployments to keep current. For a security team that already spends significant time on tooling management, adding another agent deployment pipeline is a genuine cost.
Agents expand your attack surface. An agent with write permissions to cloud resources is a privilege escalation risk. If the agent's IAM role is over-permissioned (which happens, because agents often request broad permissions to handle edge cases), a compromised agent becomes a foothold. The principle of least privilege applies to security tools as much as to anything else.
Cross-account agent deployment requires an account vending process integration. If you use AWS Control Tower or a custom account vending pipeline, adding a new agent means integrating it into that pipeline so new accounts automatically get the agent deployed. That's an integration maintenance burden that compounds as the tool evolves.
Read-only API access has none of these properties. A cross-account IAM role with read-only permissions requires no deployment, no update cycle, no health monitoring, and no account vending integration. The IAM role is a static configuration artifact that doesn't break when the version of something changes.
The Tradeoffs We Accepted
Read-only, no-agent architecture has real limitations. We accept them because they're the right tradeoffs for our specific scope.
We can't detect runtime behavioral anomalies. If a role that your SCP technically allows is being used in an unusual pattern — a data exfiltration happening through allowed API calls — we won't see it. That's a job for SIEM and CloudTrail analytics tools, not us. We're not competing with that capability because it requires different access than we want to have.
We can't remediate configuration drift automatically. If we find a coverage gap or a policy misconfiguration, we report it. We don't fix it. Automatic remediation requires write permissions, and we decided the write permission risk wasn't worth the remediation convenience. Teams that want automatic remediation should use AWS Config with auto-remediation rules, which use native AWS mechanisms rather than a third-party tool's write permissions.
Our CI/CD gate can be bypassed by direct console or CLI access. If someone with sufficient permissions deploys resources directly through the console, our CI/CD gate doesn't fire. The SCP fires. We're explicit about this: Native Security supplements your native controls, it doesn't replace them. The CI/CD gate is the developer-facing layer. The SCP is the backstop.
We think these tradeoffs are correct. A narrower, more trustworthy tool that does one thing well is more likely to be deployed and kept deployed than a comprehensive tool that requires trust in its broad permissions and complex lifecycle. Security tooling that isn't actually deployed and maintained doesn't enforce anything — which is exactly the problem we built Native Security to address.
The irony would be building a product to fix "security policies that exist but aren't actually enforced" by deploying something that itself requires extensive trust and maintenance overhead to function. We didn't want to solve the problem with a version of the same problem.