Skip to content

9.3 Authorization

Authorization answers three questions: who may act, what may they do, and on which resources? Each Moonitoring cloud service has its own identity, so reading datasets does not require the same access as operating the infrastructure. The identities themselves, for people, services and customers, are introduced in Identity & Access; this page lists what each one may do.

Historical configuration snapshot — 29 October 2026

The service/operator tables and counts below describe infrastructure commit 32e7079, not current live access. At that revision, bootstrap and stage deployment were pending the company billing choice. The pinned source links preserve that historical evidence; do not use the old project scopes, foundation/production access or assignment counts to grant access today.

Current stage and human-group rollout — 4 November 2026

Stage infrastructure is deployed and its synthetic SQL access checks passed; see the stage acceptance record. The active foundation scope is shared/stage, production remains excluded, and application images, API callers and automatic triggers remain inactive. Jacopo retains the existing named foundation/stage-operator grants and Database-project Cloud SQL Viewer access; the latter is not SQL login or Studio access.

Six security groups exist; their Google display names have a gcp prefix, their emails do not. The selected model uses one infra-admins@moonitoring.com group, stage/prod approval groups (stage-release-admins, prod-release-admins) and stage/prod observer groups (stage-observers-admins, observers-admins), all at moonitoring.com. stage-infra-admins@moonitoring.com exists but remains unused and unchanged. No IAM grants to these groups are live, and the named grants have not been removed. See the verified and pending membership checks and the team-access runbook.

9.3.1 How access is assigned

The stage phase 1 provisioned four additional empty databases and ten API/migration Google identities, verified on 5 November 2026. It left the legacy platform database and four runtime identities in place and added no SQL IAM users, Cloud SQL Client/Instance User grants or PostgreSQL privileges. The new databases are not yet isolated from existing SQL users: closing default PUBLIC CONNECT/TEMPORARY access and verifying per-component grants remains phase 2. The earlier acceptance record and historical tables below do not certify these new boundaries.

Google Cloud Identity and Access Management (IAM) assigns a role (a bundle of permissions) to an identity on a resource. For example: the dataset reader receives the object-viewer role on the datasets bucket. A grant on a project or folder can also apply to resources below it. See Google's IAM overview.

We prefer Google-managed roles. Terraform declares group/service-account assignments; terraform plan shows the proposed changes, and terraform apply makes them effective in Google Cloud. The proposed stage SQL observer is a deliberate custom-role exception: instance/database/user/backup metadata reads, without login, connect, executeSql, mutation or export. The predefined Cloud SQL Viewer includes cloudsql.backupRuns.export, so it is not equivalent to this narrower role. Editing a Terraform file alone changes no permissions.

Authorized directory administrators manage human group membership outside Terraform. A group owner approves and records additions/removals; a membership change grants only the group's assigned cloud permissions. It does not create application capabilities, tenant roles or entitlements. The selected infrastructure administrator group is intended to impersonate foundation and active-environment plan/apply identities through infrastructure_admin_groups, currently empty. It must be limited to trusted infrastructure administrators. Production access requires explicit environment activation; this input does not expand access to unrelated legacy projects or transfer organization-policy delegation. Observer groups have no impersonation or state-object access. Ordinary-log access can expose information written into logs; it is not a guarantee that the content contains no application data.

Stage release approval is a planned build/deployment gate separate from PR review, not a gate on every Google Cloud operation. It blocks the configured Cloud Build execution before plan and apply; it does not approve the exact plan generated later. Cloud Build's approver role is project-wide in the shared CI project, so separate stage/prod group names do not establish separate approval scopes. Production trigger activation is rejected while stage approver groups are configured, pending a reviewed solution. Broad infrastructure impersonation permissions can bypass this pipeline path, and group membership can overlap: the process does not enforce hard author/approver separation. No approval workflow, production group IAM, PAM or Cloud Deploy is live from this rollout. See the activation guard and review rules.

These cloud identities are separate from application users, organization memberships and roles. Cloud IAM controls access to infrastructure. Application authorization determines which farm's records a user may see.

9.3.2 Application services

This section describes the historical 29 October configuration snapshot, including its source links and then-outstanding SQL work. It is not the current deployment record.

Each row is a dedicated Google service account. Terraform creates the identities and attaches the corresponding identity to each configured workload. The table describes grants made by this configuration; it does not audit additional inherited or manually assigned access.

Identity Allowed actions Resource scope Terraform definition
platform-api Connect to Cloud SQL and authenticate with IAM Platform stage project Database access
farm-api Connect/authenticate to Cloud SQL; create and read raw objects; publish ingestion requests Farm stage project for SQL; raw bucket; ingestion-requests topic Database, raw, publisher
farm-worker Connect/authenticate to Cloud SQL; read raw objects; receive and acknowledge ingestion messages Farm stage project for SQL; raw bucket; ingestion-workers subscription Database, raw, subscriber
dataset-builder Connect/authenticate to Cloud SQL; create and read dataset objects Farm stage project for SQL; datasets bucket Database, datasets
ml-dataset-reader Read and list dataset objects Datasets bucket only in these grants Dataset reader

The assigned roles are roles/cloudsql.client and roles/cloudsql.instanceUser for database access; roles/storage.objectCreator and/or roles/storage.objectViewer for objects; and roles/pubsub.publisher or roles/pubsub.subscriber for messages. Concrete project and bucket names are in the stage inputs.

Database access still needs a second layer. Cloud SQL roles are granted at project level, while IAM database users are registered on the corresponding instance. Neither grants permission to read or modify application tables: SQL (Structured Query Language) roles, GRANT statements and row-level authorization remain to be implemented. The dataset builder's intended read access must be enforced there. See the database module's boundaries.

9.3.3 Infrastructure operators and automation

This section describes the historical 29 October configuration snapshot, including its tables, explanatory scope statements and assignment counts. It is not the current stage-only access boundary.

Deployment needs broader permissions than an application. We separate the identity that previews changes from the identity that applies them. Authorized people and build jobs can impersonate a service account: obtain temporary credentials and act with that account's permissions. This Terraform creates no service-account key files.

Identity Allowed actions Resource scope Terraform definition
sa-tf-foundation Administer foundation folders, project creation/IAM and policies; manage state objects; associate the selected billing account Five new child folders, including production; all three state buckets; selected billing account Foundation roles, billing and state
sa-stage-tf-plan Inspect resources and IAM policies; read state Stage folder and its descendants; stage state bucket Read roles, state
sa-stage-tf-apply Create/manage stage projects, network, databases, services, storage, queues and IAM; manage state and billing association Stage folder and its descendants; stage state bucket; selected billing account Apply roles, billing and state
sa-cloudbuild-validate Write build logs Build project; no infrastructure/state or impersonation grants Build grants
sa-stage-cloudbuild-plan Write build logs; impersonate sa-stage-tf-plan Build project; named plan service account Build grants
sa-stage-cloudbuild-apply Write build logs; impersonate sa-stage-tf-apply Build project; named apply service account Build grants
Named human operators Impersonate the identities listed in their allowlists Currently jtedeschi@moonitoring.com: foundation, stage plan and stage apply Allowlists, impersonation
sa-prod-tf Disabled; no operational or state grants Reserved production identity Disabled account

At that historical revision, foundation was an administrative exception across environments. Disabling sa-prod-tf did not remove foundation access to production folders and state. Build jobs received no foundation impersonation grant. That historical production scope does not describe the current shared/stage-only foundation. Stage apply is a privileged deployment identity, not an application identity.

Google also needs its own service agents to operate managed services:

Google-managed identity Allowed actions Resource scope Terraform definition
Cloud Run service agents Operate Cloud Run; inspect the shared network and use the corresponding subnet Own application project, network host project, assigned subnet Service roles, network access
Service Networking agent Manage private service connectivity Network host project Service role
Pub/Sub service agent Forward failed messages and acknowledge the source subscription ingestion-dead-letter topic and ingestion-workers subscription Dead-letter grants
Assignment counts at this revision

With the allowlists at that revision and assuming its missing inputs were supplied, the code declared 96 explicit role–identity–resource assignments: 71 for bootstrap, 16 for application/ML identities, and 9 for Google service agents. It used 37 distinct predefined roles and declared 12 user-managed service accounts, including the disabled production account.

These are not 96 individual API permissions. The count excludes automatic, inherited or pre-existing grants and the four SQL IAM users. Empty workload/caller inputs at that revision produced zero roles/run.invoker assignments. Changing those inputs or operator lists changes the count.

9.3.4 Changing access in practice

An assignment names the resource, role and identity explicitly. For example, the dataset-reader grant is:

resource "google_storage_bucket_iam_member" "ml_dataset_read" {
  bucket = module.datasets.name
  role   = "roles/storage.objectViewer"
  member = "serviceAccount:${google_service_account.ml_reader.email}"
}

To change a group's cloud role or resource scope, edit Terraform, review the plan, and follow the current team-access runbook. To join or leave an existing approved group, follow the directory membership process; a Terraform run is not required. Verify both allowed and denied operations using the affected identity. Review inherited and direct exceptions before claiming revocation or isolation. Current acceptance records accompany current grants; the pinned tables above remain historical evidence.

Farm installations are represented by SyncClient. Their authentication, application authorization and farm-level data isolation are separate implementation work. The grants above do not give each installation a Google service account or implement those controls.

9.3.5 Rules for Application Authorization

Cloud IAM decides what an identity may do to infrastructure. Inside our systems, every check follows these rules:

  • Deny by default. An action is allowed only when a role explicitly grants it.
  • Two gates for customers. The user's role must include the capability, and the user's Organization must hold the entitlement. The system checks both itself, from the token signed by access and its own copy of the entitlements published by farm (see Organizations & Access).
  • Capabilities are named <system>.<resource>.<action>, for example farm.models.use, access.members.manage or releases.releases.approve. The first part is the short name of the system that checks it (see System Overview).
  • Not authorized means not found. For something the caller may not see, a service answers exactly as if it did not exist, so nothing can be discovered by trying.
  • Staff work through the same checks. The Console holds no permissions of its own; each system checks the staff member's capabilities like any other caller.
  • Prod data needs a temporary grant, approved by a second person (see Access to Prod).