From 9ebc221608f429d41db4d18bf8dd6d9f9ec2a21a Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Fri, 23 Apr 2021 13:03:13 -0400 Subject: [PATCH 1/6] groups: remove serviceaccounts from groups the serviceaccounts are now bound directly to the appropriate roles it seems like including a serviceaccount in a group does not always propogate permissions correctly, so let's stop using it as a pattern --- groups/groups.yaml | 1 - groups/wg-k8s-infra/groups.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/groups/groups.yaml b/groups/groups.yaml index 86d378966ee..5abe6fb7a29 100644 --- a/groups/groups.yaml +++ b/groups/groups.yaml @@ -250,7 +250,6 @@ groups: - james@munnelly.eu - spiffxp@google.com - thockin@google.com - - k8s-infra-dns-updater@kubernetes-public.iam.gserviceaccount.com # # Push groups: k8s-infra-push-* diff --git a/groups/wg-k8s-infra/groups.yaml b/groups/wg-k8s-infra/groups.yaml index 48a97e158a9..6f225430815 100644 --- a/groups/wg-k8s-infra/groups.yaml +++ b/groups/wg-k8s-infra/groups.yaml @@ -126,7 +126,6 @@ groups: - cblecker@gmail.com - davanum@gmail.com - ihor@cncf.io - - k8s-infra-gcp-auditor@kubernetes-public.iam.gserviceaccount.com - k8s-infra-ii-coop@kubernetes.io - spiffxp@google.com - spiffxp@gmail.com From a646bf752b032ba958d555df600dc610de412766 Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Fri, 23 Apr 2021 17:39:54 -0400 Subject: [PATCH 2/6] infra/gcp/roles: fix regex handling Each permissionRegex is now wrapped in parentheses to become its own group when passed to grep -E. This ensures ^ and $ characters in each regex don't end up applying to the whole | concatenation of regexes. --- infra/gcp/roles/generate-role-yaml.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/infra/gcp/roles/generate-role-yaml.sh b/infra/gcp/roles/generate-role-yaml.sh index 7f5c8aaebeb..d71156b5a56 100755 --- a/infra/gcp/roles/generate-role-yaml.sh +++ b/infra/gcp/roles/generate-role-yaml.sh @@ -45,6 +45,13 @@ # generate-role-yaml.sh specs/foo.bar.yaml # diff foo.yaml foo.bar.yaml # gcloud iam roles create --project project-id foo.bar --file foo.bar.yaml +# +# Note it's possible to generate a custom role that is too large: +# +# "The total size of the title, description, and permission names for a +# custom role is limited to 64 KB" +# +# ref: https://cloud.google.com/iam/docs/creating-custom-roles set -o errexit set -o nounset @@ -73,8 +80,9 @@ function output_role_yaml() { name=$(<"${spec}" yq -r .name) mapfile -t include_roles < <(<"${spec}" yq -r '.include? | .roles//[] | .[]') mapfile -t include_permissions < <(<"${spec}" yq -r '.include? | .permissions//[] | .[]') - include_regex=$(<"${spec}" yq -r '.include? | .permissionRegexes//[] | join("|")') - exclude_regex=$(<"${spec}" yq -r '.exclude? | .permissionRegexes//[] | join("|")') + # wrap regexes in their own groups + include_regex=$(<"${spec}" yq -r '.include? | .permissionRegexes//[] | map("(\(.))") | join("|")') + exclude_regex=$(<"${spec}" yq -r '.exclude? | .permissionRegexes//[] | map("(\(.))") | join("|")') local output_path="${output_dir}/${name}.yaml" From 127d06e332b84260f2b175d87736157d1f455782 Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Fri, 23 Apr 2021 16:08:26 -0400 Subject: [PATCH 3/6] infra/gcp/roles: refresh roles --- infra/gcp/roles/audit.viewer.yaml | 35 ++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/infra/gcp/roles/audit.viewer.yaml b/infra/gcp/roles/audit.viewer.yaml index 73d0ad7c5c6..84a297e2c1e 100644 --- a/infra/gcp/roles/audit.viewer.yaml +++ b/infra/gcp/roles/audit.viewer.yaml @@ -694,8 +694,6 @@ includedPermissions: - iap.webServiceVersions.getIamPolicy - iap.webServices.getIamPolicy - iap.webTypes.getIamPolicy - - identityplatform.workloadPoolProviders.list - - identityplatform.workloadPools.list - lifesciences.operations.list - logging.buckets.list - logging.exclusions.list @@ -706,6 +704,7 @@ includedPermissions: - logging.logServices.list - logging.logs.list - logging.notificationRules.list + - logging.operations.list - logging.privateLogEntries.list - logging.queries.list - logging.sinks.list @@ -745,6 +744,12 @@ includedPermissions: - monitoring.slos.list - monitoring.timeSeries.list - monitoring.uptimeCheckConfigs.list + - networkconnectivity.hubs.getIamPolicy + - networkconnectivity.hubs.list + - networkconnectivity.locations.list + - networkconnectivity.operations.list + - networkconnectivity.spokes.getIamPolicy + - networkconnectivity.spokes.list - networkmanagement.connectivitytests.getIamPolicy - networkmanagement.connectivitytests.list - networkmanagement.locations.list @@ -773,19 +778,29 @@ includedPermissions: - notebooks.instances.list - notebooks.locations.list - notebooks.operations.list + - notebooks.runtimes.getIamPolicy + - notebooks.runtimes.list - notebooks.schedules.getIamPolicy - notebooks.schedules.list - ondemandscanning.operations.list - opsconfigmonitoring.resourceMetadata.list - osconfig.guestPolicies.list + - osconfig.instanceOSPoliciesCompliances.list + - osconfig.inventories.list + - osconfig.osPolicyAssignments.list - osconfig.patchDeployments.list - osconfig.patchJobs.list + - osconfig.vulnerabilityReports.list - policysimulator.replayResults.list - policysimulator.replays.list + - privateca.caPools.getIamPolicy + - privateca.caPools.list - privateca.certificateAuthorities.getIamPolicy - privateca.certificateAuthorities.list - privateca.certificateRevocationLists.getIamPolicy - privateca.certificateRevocationLists.list + - privateca.certificateTemplates.getIamPolicy + - privateca.certificateTemplates.list - privateca.certificates.getIamPolicy - privateca.certificates.list - privateca.locations.list @@ -808,6 +823,9 @@ includedPermissions: - pubsublite.subscriptions.list - pubsublite.topics.list - recaptchaenterprise.keys.list + - recommender.cloudAssetInsights.list + - recommender.cloudsqlInstanceDiskUsageTrendInsights.list + - recommender.cloudsqlInstanceOutOfDiskRecommendations.list - recommender.commitmentUtilizationInsights.list - recommender.computeAddressIdleResourceInsights.list - recommender.computeAddressIdleResourceRecommendations.list @@ -835,12 +853,12 @@ includedPermissions: - remotebuildexecution.workerpools.list - resourcemanager.folders.getIamPolicy - resourcemanager.folders.list + - resourcemanager.hierarchyNodes.listTagBindings - resourcemanager.organizations.get - resourcemanager.organizations.getIamPolicy - resourcemanager.projects.get - resourcemanager.projects.getIamPolicy - resourcemanager.projects.list - - resourcemanager.resourceTagBindings.list - resourcemanager.tagKeys.getIamPolicy - resourcemanager.tagKeys.list - resourcemanager.tagValues.getIamPolicy @@ -912,6 +930,7 @@ includedPermissions: - storage.buckets.getIamPolicy - storage.buckets.list - storage.hmacKeys.list + - storage.multipartUploads.list - storage.objects.getIamPolicy - storage.objects.list - storagetransfer.jobs.list @@ -923,7 +942,17 @@ includedPermissions: - tpu.tensorflowversions.list - transcoder.jobTemplates.list - transcoder.jobs.list + - vmmigration.cloneJobs.list + - vmmigration.cutoverJobs.list + - vmmigration.datacenterConnectors.list - vmmigration.deployments.list + - vmmigration.groups.list + - vmmigration.locations.list + - vmmigration.migratingVms.list + - vmmigration.operations.list + - vmmigration.sources.list + - vmmigration.targets.list + - vmmigration.utilizationReports.list - vpcaccess.connectors.list - vpcaccess.locations.list - vpcaccess.operations.list From 6d93372fab03a8e71db30d0d684e932deaad733e Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Fri, 23 Apr 2021 16:08:58 -0400 Subject: [PATCH 4/6] infra/gcp/roles: update audit.viewer specifically: - add comments explaining (or asking) why these roles/permissions - prune spec: - roles/browser better captures intent and covers more than organizationViewer - roles/iam.securityReviewer covers most storage.buckets permissions - add to spec: - roles/cloudasset.viewer in anticipation of using gcloud assets to list resources and iam roles more quickly for audit --- infra/gcp/roles/audit.viewer.yaml | 122 +++++++++++++++++++++++- infra/gcp/roles/specs/audit.viewer.yaml | 24 ++++- 2 files changed, 140 insertions(+), 6 deletions(-) diff --git a/infra/gcp/roles/audit.viewer.yaml b/infra/gcp/roles/audit.viewer.yaml index 84a297e2c1e..19cfc8a30db 100644 --- a/infra/gcp/roles/audit.viewer.yaml +++ b/infra/gcp/roles/audit.viewer.yaml @@ -7,15 +7,33 @@ # name: audit.viewer # include: # roles: +# # TODO: consider using roles/viewer instead of per-service? +# # view/read-only roles for specific services of interest +# # read access to compute # - roles/compute.viewer +# # read access to dns # - roles/dns.reader +# # read access to cloud assets metadata +# - roles/cloudasset.viewer +# +# # meta roles (regardless of roles/viewer) +# # read access for the project hierarchy (org, folders, projects) +# - roles/browser +# # list all resources and their IAM policies # - roles/iam.securityReviewer -# - roles/resourcemanager.organizationViewer +# # TODO: what specifically needs serviceusage.services.use? +# # could we use roles/serviceusage.serviceUsageViewer instead? # - roles/serviceusage.serviceUsageConsumer # permissions: +# # for gsutil _ get: cors, iam, label, logging, lifecycle, retention, ubla # - storage.buckets.get -# - storage.buckets.getIamPolicy -# - storage.buckets.list +# permissionRegexes: +# # restrict to get|list calls... +# - \.(list|get)[^\.]*$ +# # ...except for specific services of interest mentioned above +# - ^(compute|cloudasset)\. +# # ...and this specific permission from roles/serviceusage.serviceUsageConsumer +# - serviceusage.services.use # exclude: # permissionRegexes: # # permissions with custom roles support level NOT_SUPPORTED @@ -173,6 +191,100 @@ includedPermissions: - binaryauthorization.policy.getIamPolicy - clientauthconfig.brands.list - clientauthconfig.clients.list + - cloudasset.assets.analyzeIamPolicy + - cloudasset.assets.exportAccessLevel + - cloudasset.assets.exportAccessPolicy + - cloudasset.assets.exportAllAccessPolicy + - cloudasset.assets.exportAppengineApplications + - cloudasset.assets.exportAppengineServices + - cloudasset.assets.exportAppengineVersions + - cloudasset.assets.exportBigqueryDatasets + - cloudasset.assets.exportBigqueryTables + - cloudasset.assets.exportBigtableCluster + - cloudasset.assets.exportBigtableInstance + - cloudasset.assets.exportBigtableTable + - cloudasset.assets.exportCloudbillingBillingAccounts + - cloudasset.assets.exportCloudkmsCryptoKeyVersions + - cloudasset.assets.exportCloudkmsCryptoKeys + - cloudasset.assets.exportCloudkmsImportJobs + - cloudasset.assets.exportCloudkmsKeyRings + - cloudasset.assets.exportCloudresourcemanagerFolders + - cloudasset.assets.exportCloudresourcemanagerOrganizations + - cloudasset.assets.exportCloudresourcemanagerProjects + - cloudasset.assets.exportComputeAddress + - cloudasset.assets.exportComputeAutoscalers + - cloudasset.assets.exportComputeBackendBuckets + - cloudasset.assets.exportComputeBackendServices + - cloudasset.assets.exportComputeDisks + - cloudasset.assets.exportComputeFirewalls + - cloudasset.assets.exportComputeForwardingRules + - cloudasset.assets.exportComputeGlobalAddress + - cloudasset.assets.exportComputeGlobalForwardingRules + - cloudasset.assets.exportComputeHealthChecks + - cloudasset.assets.exportComputeHttpHealthChecks + - cloudasset.assets.exportComputeHttpsHealthChecks + - cloudasset.assets.exportComputeImages + - cloudasset.assets.exportComputeInstanceGroupManagers + - cloudasset.assets.exportComputeInstanceGroups + - cloudasset.assets.exportComputeInstanceTemplates + - cloudasset.assets.exportComputeInstances + - cloudasset.assets.exportComputeInterconnect + - cloudasset.assets.exportComputeInterconnectAttachment + - cloudasset.assets.exportComputeLicenses + - cloudasset.assets.exportComputeNetworks + - cloudasset.assets.exportComputeProjects + - cloudasset.assets.exportComputeRegionAutoscaler + - cloudasset.assets.exportComputeRegionBackendServices + - cloudasset.assets.exportComputeRegionDisk + - cloudasset.assets.exportComputeRegionInstanceGroup + - cloudasset.assets.exportComputeRegionInstanceGroupManager + - cloudasset.assets.exportComputeRouters + - cloudasset.assets.exportComputeRoutes + - cloudasset.assets.exportComputeSecurityPolicy + - cloudasset.assets.exportComputeSnapshots + - cloudasset.assets.exportComputeSslCertificates + - cloudasset.assets.exportComputeSubnetworks + - cloudasset.assets.exportComputeTargetHttpProxies + - cloudasset.assets.exportComputeTargetHttpsProxies + - cloudasset.assets.exportComputeTargetInstances + - cloudasset.assets.exportComputeTargetPools + - cloudasset.assets.exportComputeTargetSslProxies + - cloudasset.assets.exportComputeTargetTcpProxies + - cloudasset.assets.exportComputeTargetVpnGateways + - cloudasset.assets.exportComputeUrlMaps + - cloudasset.assets.exportComputeVpnTunnels + - cloudasset.assets.exportContainerClusterrole + - cloudasset.assets.exportContainerClusterrolebinding + - cloudasset.assets.exportContainerClusters + - cloudasset.assets.exportContainerNamespace + - cloudasset.assets.exportContainerNode + - cloudasset.assets.exportContainerNodepool + - cloudasset.assets.exportContainerPod + - cloudasset.assets.exportContainerRole + - cloudasset.assets.exportContainerRolebinding + - cloudasset.assets.exportContainerregistryImage + - cloudasset.assets.exportDatafusionInstance + - cloudasset.assets.exportDataprocClusters + - cloudasset.assets.exportDataprocJobs + - cloudasset.assets.exportDnsManagedZones + - cloudasset.assets.exportDnsPolicies + - cloudasset.assets.exportIamPolicy + - cloudasset.assets.exportIamRoles + - cloudasset.assets.exportIamServiceAccountKeys + - cloudasset.assets.exportIamServiceAccounts + - cloudasset.assets.exportManagedidentitiesDomain + - cloudasset.assets.exportOrgPolicy + - cloudasset.assets.exportPubsubSubscriptions + - cloudasset.assets.exportPubsubTopics + - cloudasset.assets.exportResource + - cloudasset.assets.exportServicePerimeter + - cloudasset.assets.exportServicemanagementServices + - cloudasset.assets.exportSpannerDatabases + - cloudasset.assets.exportSpannerInstances + - cloudasset.assets.exportSqladminInstances + - cloudasset.assets.exportStorageBuckets + - cloudasset.assets.searchAllIamPolicies + - cloudasset.assets.searchAllResources - cloudasset.feeds.list - cloudbuild.builds.list - clouddebugger.breakpoints.list @@ -823,6 +935,7 @@ includedPermissions: - pubsublite.subscriptions.list - pubsublite.topics.list - recaptchaenterprise.keys.list + - recommender.cloudAssetInsights.get - recommender.cloudAssetInsights.list - recommender.cloudsqlInstanceDiskUsageTrendInsights.list - recommender.cloudsqlInstanceOutOfDiskRecommendations.list @@ -840,6 +953,7 @@ includedPermissions: - recommender.iamPolicyInsights.list - recommender.iamPolicyRecommendations.list - recommender.iamServiceAccountInsights.list + - recommender.locations.get - recommender.locations.list - recommender.loggingProductSuggestionContainerInsights.list - recommender.loggingProductSuggestionContainerRecommendations.list @@ -851,6 +965,7 @@ includedPermissions: - redis.operations.list - remotebuildexecution.instances.list - remotebuildexecution.workerpools.list + - resourcemanager.folders.get - resourcemanager.folders.getIamPolicy - resourcemanager.folders.list - resourcemanager.hierarchyNodes.listTagBindings @@ -942,6 +1057,7 @@ includedPermissions: - tpu.tensorflowversions.list - transcoder.jobTemplates.list - transcoder.jobs.list + - translationhub.portals.list - vmmigration.cloneJobs.list - vmmigration.cutoverJobs.list - vmmigration.datacenterConnectors.list diff --git a/infra/gcp/roles/specs/audit.viewer.yaml b/infra/gcp/roles/specs/audit.viewer.yaml index e5954fd9208..ee769763719 100644 --- a/infra/gcp/roles/specs/audit.viewer.yaml +++ b/infra/gcp/roles/specs/audit.viewer.yaml @@ -5,15 +5,33 @@ description: View access to resources name: audit.viewer include: roles: + # TODO: consider using roles/viewer instead of per-service? + # view/read-only roles for specific services of interest + # read access to compute - roles/compute.viewer + # read access to dns - roles/dns.reader + # read access to cloud assets metadata + - roles/cloudasset.viewer + + # meta roles (regardless of roles/viewer) + # read access for the project hierarchy (org, folders, projects) + - roles/browser + # list all resources and their IAM policies - roles/iam.securityReviewer - - roles/resourcemanager.organizationViewer + # TODO: what specifically needs serviceusage.services.use? + # could we use roles/serviceusage.serviceUsageViewer instead? - roles/serviceusage.serviceUsageConsumer permissions: + # for gsutil _ get: cors, iam, label, logging, lifecycle, retention, ubla - storage.buckets.get - - storage.buckets.getIamPolicy - - storage.buckets.list + permissionRegexes: + # restrict to get|list calls... + - \.(list|get)[^\.]*$ + # ...except for specific services of interest mentioned above + - ^(compute|cloudasset)\. + # ...and this specific permission from roles/serviceusage.serviceUsageConsumer + - serviceusage.services.use exclude: permissionRegexes: # permissions with custom roles support level NOT_SUPPORTED From 669e3404e92c6d15f41ce3ee69a7bc880367a751 Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Wed, 5 May 2021 22:29:34 -0400 Subject: [PATCH 5/6] infra/gcp/roles: update organization.admin specifically - add comments explaining or guessing why these specific roles - add roles/billing.creator to allow creating a budget for k8s-infra-ii-sandbox - add roles/billing.costsManager because it sounds useful - add roles/storage.admin but filter to storage.buckets.* to ensure org admins have break-glass access to buckets --- infra/gcp/roles/organization.admin.yaml | 38 +++++++++++++++++++ infra/gcp/roles/specs/organization.admin.yaml | 21 ++++++++++ 2 files changed, 59 insertions(+) diff --git a/infra/gcp/roles/organization.admin.yaml b/infra/gcp/roles/organization.admin.yaml index 3f3593f1ff3..0977e679aa2 100644 --- a/infra/gcp/roles/organization.admin.yaml +++ b/infra/gcp/roles/organization.admin.yaml @@ -8,19 +8,50 @@ # name: organization.admin # include: # roles: +# # specific billing permissions we need +# # TODO(spiffxp): should we just use billing.admin? or save this for GCP accounting group? +# # maybe for resourceAssociations.create # - roles/billing.user +# # for billing.accounts.create (to create a budget for a project) +# - roles/billing.creator +# # maybe for budgets.*, this also offers accounts.updateUsageExportSpec +# - roles/billing.costsManager +# +# # resourcemanager.* permissions missing from roles/owner +# # for resourcemanager.folders.* # - roles/resourcemanager.folderAdmin +# # for resourcemanager.organizations.* # - roles/resourcemanager.organizationAdmin +# # for resourcemanager.projects.create # - roles/resourcemanager.projectCreator +# +# # for storage.buckets.(get|update|(get|set)IamPolicy) +# - roles/storage.admin +# permissionRegexes: +# # to ensure storage.buckets.* is all we get from roles/storage.admin +# - ^billing. +# - ^orgpolicy. +# - ^resourcemanager. +# - ^storage.buckets. # description: Access to administer all resources belonging to the organization includedPermissions: + - billing.accounts.create - billing.accounts.get - billing.accounts.getIamPolicy + - billing.accounts.getSpendingInformation + - billing.accounts.getUsageExportSpec - billing.accounts.list - billing.accounts.redeemPromotion + - billing.accounts.updateUsageExportSpec + - billing.budgets.create + - billing.budgets.delete + - billing.budgets.get + - billing.budgets.list + - billing.budgets.update - billing.credits.list - billing.resourceAssociations.create + - billing.resourceAssociations.list - orgpolicy.policy.get - resourcemanager.folders.create - resourcemanager.folders.delete @@ -40,6 +71,13 @@ includedPermissions: - resourcemanager.projects.list - resourcemanager.projects.move - resourcemanager.projects.setIamPolicy + - storage.buckets.create + - storage.buckets.delete + - storage.buckets.get + - storage.buckets.getIamPolicy + - storage.buckets.list + - storage.buckets.setIamPolicy + - storage.buckets.update name: organization.admin stage: GA title: Organization Admin diff --git a/infra/gcp/roles/specs/organization.admin.yaml b/infra/gcp/roles/specs/organization.admin.yaml index 42f76ecce96..e3ca4677027 100644 --- a/infra/gcp/roles/specs/organization.admin.yaml +++ b/infra/gcp/roles/specs/organization.admin.yaml @@ -6,7 +6,28 @@ description: Access to administer all resources belonging to the organization name: organization.admin include: roles: + # specific billing permissions we need + # TODO(spiffxp): should we just use billing.admin? or save this for GCP accounting group? + # maybe for resourceAssociations.create - roles/billing.user + # for billing.accounts.create (to create a budget for a project) + - roles/billing.creator + # maybe for budgets.*, this also offers accounts.updateUsageExportSpec + - roles/billing.costsManager + + # resourcemanager.* permissions missing from roles/owner + # for resourcemanager.folders.* - roles/resourcemanager.folderAdmin + # for resourcemanager.organizations.* - roles/resourcemanager.organizationAdmin + # for resourcemanager.projects.create - roles/resourcemanager.projectCreator + + # for storage.buckets.(get|update|(get|set)IamPolicy) + - roles/storage.admin + permissionRegexes: + # to ensure storage.buckets.* is all we get from roles/storage.admin + - ^billing. + - ^orgpolicy. + - ^resourcemanager. + - ^storage.buckets. From ebece4e7c78136ea161d135c4bce66952d67db70 Mon Sep 17 00:00:00 2001 From: Aaron Crickenberger Date: Wed, 5 May 2021 22:54:55 -0400 Subject: [PATCH 6/6] infra/gcp/org: give org admins orgpolicy.policyAdmin role --- infra/gcp/ensure-organization.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/infra/gcp/ensure-organization.sh b/infra/gcp/ensure-organization.sh index 00d22f17da8..1621f2021f0 100755 --- a/infra/gcp/ensure-organization.sh +++ b/infra/gcp/ensure-organization.sh @@ -52,6 +52,9 @@ org_role_bindings=( # https://cloud.google.com/storage/docs/access-control/iam-roles#basic-roles-intrinsic "group:k8s-infra-gcp-org-admins@kubernetes.io:roles/owner" "group:k8s-infra-gcp-org-admins@kubernetes.io:$(custom_org_role_name "organization.admin")" + # orgpolicy.policy.set is not allowed in custom roles, this is the only role that has it + "group:k8s-infra-gcp-org-admins@kubernetes.io:roles/orgpolicy.policyAdmin" + # empower k8s-infra-prow-oncall@ to use GCP Console to navigate to their projects "group:k8s-infra-prow-oncall@kubernetes.io:roles/browser"