Push-mode cloud scanning is live
You can now run the PostQ cloud scanner in your own AWS account or Azure subscription and stream results back to your PostQ dashboard — without granting PostQ a cross-account role.
Until today, the only way to use the PostQ cloud scanner on your own infrastructure was to either run it from your laptop (the postq scan cloud aws CLI command) or to grant the PostQ API a cross-account IAM role and have us assume into your account from our infrastructure. Both are fine for evaluation; neither is great for the security team that (correctly) doesn’t want to extend trust to a vendor account for continuous scanning.
Today we’re shipping the third option: push-mode ingest. You deploy the scanner inside your own AWS account or Azure subscription, it enumerates resources locally on whatever schedule you set, and it POSTs the raw inventory to the new POST /v1/ingest/cloud endpoint on the PostQ API. We classify, score, and store the results into the same dashboard tables that the existing pull-mode and CLI flows already write to.
The three install modes, side by side
PostQ now supports three legitimate ways to scan a cloud account. Customers should pick whichever matches their security posture — they’re not graduations of one another, they’re different trade-offs.
| Mode | Where the scanner runs | Trust extended to PostQ | Best for |
|---|---|---|---|
| CLI | your laptop / CI runner | none (uses your local creds) | dev, CI gates, ad-hoc audits |
| Pull (AssumeRole) | PostQ infrastructure | cross-account IAM role / service principal | fast first-touch evaluation, on-demand scans |
| Push (today) | your own AWS account / Azure sub | none beyond the API key | continuous prod monitoring, GovCloud, private VPCs |
This is the same model Wiz, Orca, and Datadog Cloud Security all converged on. Don’t pick one; let the security team pick.
What landed today
The single concrete change in this release is one new endpoint plus its OpenAPI contract. Everything else is the four PRs lined up behind it.
POST https://api.postq.dev/v1/ingest/cloud
Authorization: Bearer pq_live_…
Content-Type: application/json
{
"provider": "aws",
"target": "123456789012",
"timestamp": "2026-04-25T09:14:33Z",
"regionsScanned": ["us-east-1","us-west-2","eu-west-1"],
"resources": [
{
"id": "arn:aws:kms:us-east-1:123…:key/abcd-…",
"name": "alias/release-signing-prod",
"type": "KMS Key",
"region": "us-east-1",
"algorithm": "RSA_2048",
"usage": "SIGN_VERIFY"
},
{
"id": "arn:aws:acm:us-east-1:123…:certificate/…",
"name": "*.example.com",
"type": "ACM Certificate",
"region": "us-east-1",
"algorithm": "RSA-2048",
"keySize": 2048
}
],
"agent": { "name": "postq-aws-scanner", "version": "1.0.0" }
}The agent ships raw resources. The PostQ API does the risk classification (RSA-2048 / ECC-P256 / ECDSA → HIGH; AES-256 / ML-DSA / ML-KEM → LOW or NONE), computes the org-level risk score, and persists into the same scans, scan_findings, keys, and assets tables that pull-mode scans already write to. From the dashboard’s point of view, push-mode scans are indistinguishable from any other scan — same risk score, same finding rows, same asset inventory, same CI-friendly scan-list / asset-list APIs for SDKs and the CLI.
Two reasons we put the classification on the server, not in the agent:
- The classifier evolves. When NIST publishes a new ML-DSA parameter set, or we tighten the scoring on RSA-3072, we want every push-mode scanner in the world to pick that change up immediately — not after a customer re-deploys their CloudFormation stack.
- Agents stay tiny. The current AWS Lambda agent is well under 10 MB and has zero policy logic in it. It enumerates, it POSTs, it’s done. The attack surface inside the customer’s account is limited to read-only KMS / ACM / ELB / S3 listing.
The four PRs landing next
Today’s endpoint is the keystone. Now that the wire format is locked in, the rest of the work can land in parallel:
- AWS Lambda + CloudFormation, wired and published. We already have a working Lambda that enumerates KMS, ACM, ALB listeners, S3 bucket encryption, Secrets Manager, and CloudFront. It currently posts to the wrong endpoint — we’re rewiring it to
/v1/ingest/cloudand publishing the CloudFormation template to a public S3 bucket so “Launch Stack” deep-links work straight from the dashboard. - Real Azure Key Vault scanner. The Azure pull-mode path is currently a mock. We’re shipping a real
azure-kv.tsthat mirrors the existing AWS KMS scanner: service-principal or managed-identity auth, enumeration across the subscription, classification of RSA / RSA-HSM / EC / EC-HSM keys. - Azure Container Apps Job + Bicep. Push-mode for Azure: a small container image (
ghcr.io/postqdev/postq-azure-scanner), a Bicep template that provisions a managed identity withKey Vault Reader+ subscription-scopeReader, and a Container Apps Job on a cron schedule. The Bicep compiles to ARM JSON, hosted next to the CloudFormation template, so the Deploy to Azure button works the same way Launch Stack does for AWS. - A new public repo:
postq-deploy. All the customer-installable templates — CloudFormation, Bicep, Helm, Terraform — live in one public, browsable repo. GoReleaser-style workflow on tag publishes the release artifacts to S3 and GHCR. Customers in regulated environments fork and audit before deploying. That’s how the Datadog Helm chart and the Wiz CLI ship; we’ll do the same.
A note on the auth model
The push-mode endpoint is gated by the same API-key auth as every other v1 endpoint, with the scan:write scope required. Generate a key under Settings → API keys with the appropriate scope set, store it in the customer-side secret manager (AWS SSM Parameter Store, Azure Key Vault), and inject it into the scanner job’s environment. The scanner never sees any other org’s data; the API key is the only identifier needed to attribute findings to the right org.
For tighter ops postures we’ll add per-key IP allowlists and per-key scope-narrowing (push-only keys that can’t list other scans, mint hybrid keys, etc.) in a follow-up. The schema is already in the database; the dashboard UI is the gating piece.
Try it
The endpoint is live now at https://api.postq.dev/v1/ingest/cloud. The OpenAPI spec has the full schema. If you want to push us a hand-rolled inventory today before the AWS Lambda + Azure Container Apps Job templates are out, the request shape above is all you need.
The “Connect a cloud” page in the dashboard, with one-click Launch Stack / Deploy to Azure buttons for the templates, lands with PR #6 in the sequence. We’ll write that one up separately. For now: if you’ve been waiting on push mode because pull mode wouldn’t pass your security review, the contract is finally there. Talk to us if you want early access to the AWS Lambda template before the public S3 publish.