A connector is how the agent verifies something instead of asking a human for a screenshot.
That is the whole value proposition, and it is measurable. The control catalog marks each of its 86 controls with how much of the work a machine can do:
| Automation | Controls | Meaning |
|---|---|---|
agent_collectable |
41 | The agent can produce the evidence by itself |
hybrid |
37 | The agent does the work, a human signs off |
human_required |
12 | Interviews, legal review, physical checks |
Connectors are what turn those 41 into zero-conversation controls. Everything else in the product — outreach, escalation, SLAs — exists to handle the other 49.
What is implemented
| Connector | Auth | Claims | Of which machine-verifiable |
|---|---|---|---|
| GitHub | fine-grained read-only token | 13 controls | 7 |
| Okta | read-only API token | 13 controls | 8 |
| Microsoft Entra ID | app registration + admin consent | 15 controls | 9 |
| Amazon Web Services | read-only role (or static keys) | 16 controls | 12 |
| Google Cloud | service account key, read-only scope | 20 controls | 13 |
| Microsoft Azure | Reader role on the subscription | 19 controls | 15 |
| Google Workspace | service account with domain-wide delegation | 8 controls | 4 |
| 38 unique | 26 |
They cover 26 of the 41 machine-verifiable controls (63%) and 38 of the 90 controls overall, and they span both major clouds and both major identity providers: an identity connector that only speaks Okta excludes most small companies, and a cloud connector that only speaks AWS excludes the ones on GCP or Azure. Google Workspace deliberately duplicates Okta and Entra ID rather than adding new controls - a customer has one identity provider, and the numbers above count a shared control once.
Four of them (Okta, Entra ID, Google Workspace, Slack) also implement listDirectory, so the same
credential that answers "is MFA enforced?" also answers "who works here?". That is what lets the agent
address a finding to a person instead of filing it in a dashboard.
What each one actually checks
GitHub — organisation-wide 2FA requirement, members who have not enrolled, outside collaborators,
branch protection on every default branch, open secret-scanning alerts, open critical/high Dependabot
advisories. Evidences change management (CC8.1, A.8.25), access (CC6.1, CC6.3, A.5.15,
A.5.19), identity (A.8.5, PR.AA-03) and secure development (A.8.28, A.8.8, ID.RA-01).
Okta — whether the sign-on policy requires a second factor (policy and population are different
facts, and auditors ask for both), active users with no factor enrolled, who holds privileged roles,
dormant accounts (90 days), suspended accounts that still exist, password policy, session lifetime.
Evidences A.8.5, A.8.2, A.5.17, A.5.18, CC6.2, CC6.3, A.6.5, PR.AA-01, PR.AA-03.
Microsoft Entra ID — whether a conditional access policy actually requires MFA for all users (a
report-only policy does not count), users with no authentication method registered, privileged role holders
with global administrators counted separately, accounts dormant for 90 days, guest accounts with standing
access, and registered devices that are not managed. Evidences A.8.5, A.8.2, A.5.16–A.5.19, A.8.1,
CC6.1–CC6.3, A.6.5, PR.AA-01, PR.AA-03, ID.AM-01. The MFA report, conditional access and
sign-in activity need a P1 licence; when it is missing the connector says so rather than reporting a clean
directory.
AWS — root account MFA and root access keys, IAM users without MFA, S3 buckets without public
access blocks, unencrypted RDS and EBS, CloudTrail presence/multi-region/log validation, security
groups exposed on SSH/RDP/database ports, database backup retention. Evidences A.8.24, PR.DS-01,
CC6.6, CC6.7, A.8.15, DE.CM-01, A.8.20, A1.3, A.8.13.
Google Cloud — buckets with public IAM bindings (read from the bucket policy, which is the exposure,
rather than from an access-block setting that proxies for it), buckets without uniform access, project IAM
grants to allUsers, primitive Owner and Editor bindings, whether Data Access audit logs are configured
(read from the project policy, because GCP has no separate trail resource), firewall rules open to the
internet, Cloud SQL with a public IP, no TLS requirement or no backups, and compute instances with external
addresses.
Microsoft Azure — storage accounts allowing public blob access or accepting HTTP or TLS below 1.2, network security group rules open to the internet on administrative ports, Azure SQL servers reachable from the internet, Key Vaults that can be permanently deleted or that still use access policies instead of RBAC, whether subscription activity is exported anywhere, and users holding Owner or Contributor at subscription scope.
Which connectors to add next
Ordered by controls unlocked per unit of effort, using the gap analysis below.
1. Google Workspace: the two cheap wins that remain (~half a day)
The connector itself is implemented — 2SV enrolment, suspension and dormancy, plus the roster. What is still missing from that batch, and needs no extra credential:
- DMARC, SPF and DKIM on the customer's domain. This is a DNS lookup, and "email authentication is not configured" is a finding in nearly every SMB review.
- Mailbox forwarding rules to external addresses, the persistence mechanism in most business email compromise cases.
Both belong in the connector that already has the domain name to hand.
2. Endpoint management — Jamf, Kandji, Intune (~a day)
Four machine-verifiable controls are currently uncovered purely because nobody can see the laptops:
A.8.1 (endpoint devices), A.8.7 (malware protection), ID.AM-01 (hardware inventory) and parts of
CC6.1. The checks are the classic ones: FileVault/BitLocker status per device, OS version against a
minimum, screen lock enforced, EDR agent present, and devices that have not checked in for 30 days.
3. Jira or Linear (~half a day)
Not a verification connector at all — this is the record category. The agent's whole theory is that work gets done when it lands in the team's existing backlog, with the owner and deadline they already respect. Today remediation is tracked inside CISO Express and reaches people through chat; a ticket that appears in the sprint is a stronger guarantee that a fix ships. One-way push first (issue → ticket), two-way sync second.
4. A scanner — Snyk, or Dependabot for non-GitHub users (~half a day)
GitHub's Dependabot covers repositories it hosts. Customers on GitLab, Bitbucket or a self-hosted GitHub need the scanner directly. Snyk's REST API is a token and two endpoints, and the mapping is identical to the existing Dependabot logic, so this is mostly a re-implementation of one function.
5. Datadog, CloudWatch or Grafana (~half a day)
Covers A.8.16 and DE.CM-09 (monitoring) and A1.2 (availability), and lets the agent file
incident evidence: which alerts fired, who acknowledged them, how long to resolution. That is the
sample an auditor asks for under CC7.2–CC7.4, and it is the one most companies fail to produce.
6. Platform-side checks that need no customer credential (a few hours)
Worth calling out separately because they cost the customer nothing:
| Check | Unlocks |
|---|---|
| TLS configuration and certificate expiry on public endpoints | PR.DS-02, CC6.7 |
| DNS: SPF, DMARC, DKIM, dangling CNAMEs | A.5.14, CC6.6 |
| Subdomain takeover candidates | A.8.20, A.5.23 |
| Security advisories for the customer's dependency list | A.5.7 |
These are the only connector-shaped features where the agent needs nothing from the customer at all, which makes them the cheapest possible first value in a trial.
7. HRIS — BambooHR, Gusto, Rippling (~a day)
Joiners, movers and leavers are the input to half the access-control controls (CC6.2, A.6.1,
A.6.5), and the leaver feed is what makes "access removed within 24 hours" verifiable rather than
asserted. It also carries background-check completion.
The gap analysis
Of the 41 machine-verifiable controls, 26 are covered today. The remaining 15, and what would cover each:
| Uncovered control | Needs |
|---|---|
A.1.2 availability monitoring, A.8.16, DE.CM-09, PCI Req 10 |
A monitoring connector: Datadog, CloudWatch or Grafana. With identity and cloud covered this is now the largest single gap - four controls from one integration |
CC3.2 risk identification, CC4.1 monitoring of controls, CC5.1 segregation of duties |
IdP role data, partially reachable now: the Okta and Entra ID connectors already read role assignments, so what is missing is conflicting-pair analysis and a place to record a compensating control |
A.5.7 threat intelligence |
Advisory feeds for the dependency list (no credential needed) |
A.5.9, ID.AM-02 inventory |
MDM plus SaaS discovery through the identity provider's application list |
A.8.7 malware protection |
MDM / EDR |
A.8.9 configuration management |
Cloud plus IaC, extending the three cloud connectors |
HIPAA 164.312(a)(b)(e) |
Not a new connector: the existing identity and cloud connectors applied to a defined ePHI scope |
Two of these deserve a note. Segregation of duties is genuinely hard and usually faked by tools: it needs a mapping from role to conflicting permission and a judgement call about whether a small team can avoid the conflict at all. Rather than pretend, the agent surfaces the conflicting pairs it finds and asks the CISO to record a compensating control. HIPAA and PCI are not new connectors so much as scopes: the same identity and cloud checks applied to a subset of systems, which is why the scope model has to come before the connector.
Adding a connector
Implement Connector (services/agent/src/connectors/types.ts):
collect(context): Promise<ConnectorResult>
Return two things, and be honest about the second:
findings— what is wrong. Each carries a stableref, a severity, the controls it undermines, remediation steps and a preferredownerRole.evidence— what is already fine. Each names the control it evidences and how long it stays true. This is the half that removes work from a human, so it deserves as much care as the findings.checkedControls— everything you looked at, whether it passed or not, so coverage is visible.warnings— partial failures. Never let a permission error look like a clean bill of health.
Rules that are not optional:
- Read-only. No connector may write to a customer system. Remediation goes through the customer's own process; the agent's job is to say what is wrong and who owns it.
- Bound the work. Use
maxItemsOf/budgetOfand report when you hit a cap. "Sampled 100 of 2,341 users" is honest; silently checking 100 and implying full coverage is not. - A missing permission is a warning, not silence. The customer needs to know what was not checked, because an auditor will ask.
- Stable
refs.sync.tsdeduplicates on them, closes issues when they disappear and reopens them if they come back. An unstable ref turns one finding into a new issue every night.
Then add tests in services/agent/src/__tests__/connectors.test.ts: a stubbed-fetch test for the happy
path, one for the failure path, and — for anything with a signature or a parser — a check against a
reference implementation. The AWS signer is verified against a signature produced by botocore itself
rather than against its own output, which is the only way that kind of test is worth anything.
Limitations worth knowing
- Cadence is daily. Connectors run in the evidence pass, once a day per workspace. These APIs change slowly and several have rate limits that a 15-minute sweep would exhaust.
- Sampling is bounded. The Okta connector reads factors one user at a time, so it samples by default and says so in its summary. Read-only directory APIs are the bottleneck, not the agent.
- AWS uses the XML query protocol. Keyless:
xml.tsis deliberately small. If the agent ever needs attributes, namespaces or CDATA from an AWS response, that is a signal to use a different API rather than to grow the parser. - No writes. Nothing here creates a ticket, rotates a key or disables an account. That is a deliberate boundary: the agent recommends, the customer's own tooling and process act.