Netra documentation

A read-only Azure ISM PROTECTED posture reporter & best-practice hardening scanner.

01What it is

Netra deploys into your own Azure tenant and reads it — with nothing but the Reader role and, once you consent, a read-only Microsoft Graph permission. It reports where you stand against the Australian Government ISM at PROTECTED, and recommends best-practice hardening mapped to CIS, NIST 800-53, the Microsoft Cloud Security Benchmark and the ACSC Blueprint. It writes nothing to your tenant.

Netra console — scan summary with compliance donut

The console: a read-only scan of all 986 PROTECTED controls, a compliance donut, and a branded PDF report.

02Five evidence planes

PlaneReadsNeedsStatus
InfrastructureAzure Resource Graph — encryption, TLS, NSGs, backup, patch assessmentReaderlive
EmailPublic DNS — SPF, DKIM, DMARC, MTA-STSnothing (public)live
IdentityEntra — MFA, Conditional Access, security defaultsPolicy.Read.All (read-only)consent
GuestVM hardening — Machine Config & Azure Run Command (ASR, Print Spooler, LDAP signing)runCommand/actionopt-in
DirectoryAD account hardening over read-only LDAP (reversible encryption, Kerberos pre-auth, unconstrained delegation)DC route + read credentialopt-in

03Verdicts & honesty

Absence is never a pass. A control with no evidence is Not assessed; a check whose prerequisite is missing is No visibility; neither is Effective. Every technical mapping is partial — it proves a necessary condition, not the whole control — and states its limitations. Manual attestation covers the residual but can never override a determined machine finding: a person cannot sign away a real result.

Coverage is deliberately honest: roughly a fifth of PROTECTED controls are technically checkable at all; the rest are governance, personnel and process, answered by attestation. Netra never inflates its own coverage.

04Controls, attestation & decisions

Every ISM control, correlated with the scan. Where the scan proved a control you see it; where it saw nothing you attest it (verdict, justification, attestor); and where it found a negative you decide what to do — remediate, accept the risk, record a compensating control, or dispute it. A compensating control or a disputed false positive reports Effective (the machine result kept alongside); risk-acceptance and remediation keep the finding and record the treatment. A guided walkthrough steps through everything that needs action.

Netra Controls — deciding what to do about a machine-negative control

A machine-negative control, and the operator deciding its treatment — tracked with owner, date and justification.

The one artefact your assessor needs is the merged PDF report: it fuses the machine scan with your attestations and decisions, so a compensating control or accepted risk shows against its control. Attestations and decisions are stored in the deployment's own managed Postgres, so they survive restarts and one-command upgrades.

05Install

From Azure Cloud Shell (Bash), in the target subscription:

curl -sL https://netra.run/install.sh | bash -s -- --region australiaeast

This creates a resource group rg-netra with a user-assigned managed identity, Log Analytics, and a single-replica Container App; registers an Entra app for sign-in; provisions a managed Postgres for your attestations and decisions; and grants the identity Reader on the subscription. Infrastructure, email and hardening checks work immediately.

Upgrading in place

Upgrades are a single command — an image-only roll. The database is untouched, and the app applies its Flyway schema migrations on startup, so code and schema move forward with zero data loss. It never re-runs the install stack (which would stand up a fresh, empty database).

curl -sL https://netra.run/upgrade.sh | bash              # latest published version
curl -sL https://netra.run/upgrade.sh | bash -s -- --image-tag 0.3.1

The app also checks the public version feed and shows an in-console banner when a newer version is available — the check runs in your browser, so the deployment makes no outbound call.

Active Directory line-of-sight (optional)

The Directory plane binds over LDAP from Netra's own network to a domain controller. A default install has no route to your DC subnet, so that plane reports "no DC reachable" until you give it line-of-sight. To enable it, run Netra inside your VNet and make sure that VNet can reach the DC:

  1. Create (or choose) a subnet for Netra's Container Apps environment — delegate it to Microsoft.App/environments, size /23 or larger.
  2. Give that VNet a route to the DC's network — VNet peering (for an IaaS/AD DS DC in Azure), or a site-to-site VPN / ExpressRoute for on-premises.
  3. Allow 636/TCP (LDAPS) from Netra's subnet to the domain controller (NSG / firewall). Prefer LDAPS so the bind credential is never in the clear.
  4. Install with the subnet supplied — and, if you want the database private too, pass a delegated Postgres subnet and its private DNS zone (the DB then has no public endpoint):
curl -sL https://netra.run/install.sh | bash -s -- --region australiaeast \
  --infrastructure-subnet /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Network/virtualNetworks/<vnet>/subnets/<aca-subnet> \
  --db-subnet   /subscriptions/<sub>/.../subnets/<pg-subnet> \
  --db-dns-zone /subscriptions/<sub>/.../privateDnsZones/privatelink.postgres.database.azure.com

Then, in the console's Directory tab, supply a read-only directory account and hit Test & discover — Netra binds, confirms reachability, and discovers the naming context. It only ever reads.

The three flags go together. --db-subnet makes Postgres VNet-private — no public endpoint at all — so Netra itself must also run inside that VNet (--infrastructure-subnet), and the private DNS zone (--db-dns-zone) is required for the server name to resolve from inside it. Supplying --db-subnet on its own would leave the app unable to reach its own database, so the installer refuses that combination up front. Recommended for PROTECTED workloads. Without these flags the database keeps its Azure-services-only endpoint, protected by the admin password and enforced TLS.

06Permissions & consent

When a plane needs a permission it isn't granted, Netra surfaces the ask in the console — with the reason, the controls it unlocks, and two ways to grant it:

One-click portal consent

A deep link straight to the admin-consent flow for Netra's app.

Azure CLI grant

graphSpId=$(az ad sp list --filter "appId eq '00000003-0000-0000-c000-000000000000'" --query '[0].id' -o tsv)
roleId=$(az ad sp show --id 00000003-0000-0000-c000-000000000000 \
  --query "appRoles[?value=='Policy.Read.All'].id | [0]" -o tsv)
az rest --method POST \
  --uri "https://graph.microsoft.com/v1.0/servicePrincipals/$graphSpId/appRoleAssignedTo" \
  --body "{\"principalId\":\"<NETRA_MI_OBJECT_ID>\",\"resourceId\":\"$graphSpId\",\"appRoleId\":\"$roleId\"}"

The console pre-fills your managed identity's object id. Every permission Netra asks for is read-only.

Netra findings with gain-visibility help

A no-visibility finding shows the exact read-only grant that lets Netra assess it definitively — or attest it instead.

07Managed identity

Netra reads your tenant as a user-assigned managed identity named netra-mi. The console shows it prominently — its object id, client id, and that it holds Reader and nothing else. There is no service account password and no baked secret; Azure access is via the managed identity, and the only secret is the Entra sign-in client secret, injected as a Container App secret.

Netra Access tab — the managed identity and what it holds

The Access tab names the exact managed identity reading your tenant, what it holds today, and how to widen it.

08Teardown

az stack group delete --name netra -g rg-netra --action-on-unmanage deleteAll --yes
az group delete -n rg-netra --yes
# then remove the Reader role assignment and the Entra app (ids printed by the installer)

09Frameworks

One scan, mapped to every framework a finding touches — pinned to versions:

FrameworkVersion
Australian Government ISM (PROTECTED)ASD OSCAL release
CIS Microsoft Azure Foundations Benchmarkv2.0.0
CIS Microsoft 365 Foundations Benchmarkv4.0.0
NIST SP 800-53Rev. 5
Microsoft Cloud Security Benchmarkv1
ASD Blueprint for Secure Cloudcurrent
Framework control identifiers are curated references, not verbatim benchmark text, and should be verified against the pinned source version.

10Security posture

Read-only by construction (Reader; Resource Graph has no mutation API). No baked secrets — managed identity for Azure. Entra OIDC sign-in, fail-closed. The higher-privilege guest and directory planes are opt-in and off by default. Attestations, decisions and branding persist in the deployment’s own managed Postgres, so upgrades preserve them. The install templates are public and the full source is available to security teams on request — security@netra.run.