Domain-restricted sharing: what to send your org admin
If you are reading this because a grant failed with FAILED_PRECONDITION,
or because Nodrik says a project is not connected when you are sure you
granted it, this is almost certainly why.
This page is written for your organisation administrator. If that is not you, send them the link. They have never heard of us, so everything below says what is being asked for and why, rather than assuming they already know.
What is happening
Section titled “What is happening”Your organisation enforces the
constraints/iam.allowedPolicyMemberDomains org policy, usually called
domain-restricted sharing. It refuses any IAM role binding to a
principal outside your own Cloud Identity customer.
Nodrik’s service account for your workspace lives in our Google Cloud project, not yours — one dedicated account per customer, which is the same design that stops any Nodrik customer’s identity reaching another’s. So under that constraint, every one of the four read-only bindings is refused.
This is a deliberate security setting, not a misconfiguration. It is a good one, and we are not asking anyone to turn it off. It needs an exception, and the first of the two routes below is narrow enough to be a reasonable thing to ask for.
Nothing has been changed in your project. Google refuses the binding before it is written, so a refused grant leaves no partial state. Once an exception is in place, re-run whichever path you used and it picks up where it stopped — the grant commands are idempotent.
Why Nodrik does not warn you before you try
Section titled “Why Nodrik does not warn you before you try”Reading an org policy needs orgpolicy.policy.get at the organisation,
plus the Org Policy API enabled on the project. The person this most
affects — somebody connecting a single project, with no organisation-level
access — has neither. A pre-flight check would fail for exactly the people
who need the warning.
Worse, when the Org Policy API is disabled, gcloud offers to enable it
for you. That is a write, on your project, from a procedure that
promises to change nothing, and we will not do it.
So Nodrik attempts the binding and classifies the refusal instead. The attempt needs no extra permission and no extra API, and it cannot give a false answer.
What needs to be allowed
Section titled “What needs to be allowed”One service account, dedicated to this workspace, shaped like:
tenant-<your-workspace>@tg-shard-<n>.iam.gserviceaccount.comThe exact address is shown in the console on the Connect a Google Cloud project step, and it is printed by the script and the Terraform module. Use that value verbatim — it is specific to your workspace and is not the same for any other customer.
It is being granted four viewer roles and nothing else:
roles/logging.viewer, roles/monitoring.viewer,
roles/errorreporting.viewer, roles/run.viewer. No path ever requests a
write role. The full account of what those read is on the
overview page.
Route 1: an exception scoped to this one project (preferred)
Section titled “Route 1: an exception scoped to this one project (preferred)”This leaves domain-restricted sharing enforced everywhere else in your organisation, and lifts it only on projects carrying a tag you control. It is the narrower of the two and the one to try first.
Replace ORG_ID with your organisation id
(gcloud organizations list) and PROJECT_ID with the project being
connected.
Create the tag and bind it to the project:
gcloud resource-manager tags keys create nodrik \ --parent organizations/ORG_ID
gcloud resource-manager tags values create allowed \ --parent ORG_ID/nodrik
gcloud resource-manager tags bindings create \ --tag-value ORG_ID/nodrik/allowed \ --parent //cloudresourcemanager.googleapis.com/projects/PROJECT_IDThen write exception.yaml:
name: projects/PROJECT_ID/policies/iam.allowedPolicyMemberDomainsspec: inheritFromParent: true rules: - allowAll: true condition: expression: "resource.matchTag('ORG_ID/nodrik', 'allowed')"And apply it:
gcloud org-policies set-policy exception.yamlSuccess looks like: gcloud org-policies describe iam.allowedPolicyMemberDomains --project PROJECT_ID --effective shows the
conditional rule, and re-running the grant no longer fails.
Route 2: add Nodrik to the allowlist
Section titled “Route 2: add Nodrik to the allowlist”Wider, because it permits Nodrik principals in every project in your organisation that inherits the policy. Use it if the tag route does not fit how your organisation manages policy.
Add Nodrik’s Cloud Identity customer id to the constraint’s allowed
values. The console shows that id on the blocked screen when it has it;
if it does not, ask us at support@nodrik.dev and we will send it. We
deliberately do not print a placeholder here: a customer id pasted from a
document is a policy that allows the wrong organisation, which is a worse
outcome than a policy that allows nothing.
After the exception
Section titled “After the exception”Re-run the grant by whichever path you started with — the console wizard, the script, or Terraform — and then check it from the console’s Settings page. See Verify access for what each pill means.
If a project still reads not connected after the exception is in place
and the grant has been re-run, the cause is something else. Send us the
project id at support@nodrik.dev.
Reference
Section titled “Reference”- Restricting identities by domain — Google’s own documentation for this constraint.
- Setting an org policy with tags — the conditional mechanism Route 1 uses.