Esta página descreve como gerenciar o acesso a recursos específicos usando vinculações de papéis condicionais nas suas políticas de permissão. Ao usar atributos de recurso em uma expressão de condição, é possível controlar se um principal pode usar uma permissão para acessar um recurso com base no nome, tipo e Google Cloud do recurso.
Antes de começar
- Leia a Visão geral das condições do Identity and Access Management (IAM) para entender os princípios básicos das vinculações de papéis condicionais do IAM.
- Consulte os atributos de recurso que podem ser usados em uma expressão de condição.
- O atributo de nome do recurso pode controlar o acesso aos
seguintes serviços do Google Cloud :
- Apigee
- Application Integration
- Hub de APIs da Apigee
- Serviço de backup e DR
- BigQuery
- API BigQuery Reservation
- Bigtable
- Autorização binária
- Cloud Deploy
- Cloud Key Management Service
- Cloud Logging
- Cloud SQL
- Cloud Storage
- Compute Engine
- Dataform
- Google Kubernetes Engine
- Firestore
- Conectores de integração
- Google Cloud Managed Service para Apache Kafka
- Pub/Sub Lite
- Secret Manager
- Spanner
Funções exigidas
Para conseguir as permissões necessárias para gerenciar vinculações de papéis condicionais, peça ao administrador para conceder a você os seguintes papéis do IAM:
-
Para gerenciar o acesso aos projetos:
Administrador do IAM do projeto (
roles/resourcemanager.projectIamAdmin
) no projeto -
Para gerenciar o acesso às pastas:
Administrador de pastas (
roles/resourcemanager.folderAdmin
) na pasta -
Para gerenciar o acesso a projetos, pastas e organizações:
Administrador de organização (
roles/resourcemanager.organizationAdmin
) na organização -
Para gerenciar o acesso a quase todos os recursos do Google Cloud :
Administrador de segurança (
roles/iam.securityAdmin
) no projeto, na pasta ou na organização com os recursos que você quer gerenciar.
Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.
Esses papéis predefinidos contêm as permissões necessárias para gerenciar vinculações de papéis condicionais. Para conferir as permissões exatas necessárias, expanda a seção Permissões necessárias:
Permissões necessárias
As permissões a seguir são necessárias para gerenciar vinculações de papéis condicionais:
-
Para gerenciar o acesso aos projetos:
-
resourcemanager.projects.getIamPolicy
no projeto -
resourcemanager.projects.setIamPolicy
no projeto
-
-
Para gerenciar o acesso às pastas:
-
resourcemanager.folders.getIamPolicy
na pasta -
resourcemanager.folders.setIamPolicy
na pasta
-
-
Para gerenciar o acesso a organizações:
-
resourcemanager.organizations.getIamPolicy
na organização -
resourcemanager.organizations.setIamPolicy
na organização
-
Essas permissões também podem ser concedidas com funções personalizadas ou outros papéis predefinidos.
Conceder acesso a um grupo de recursos com base em prefixos de nomes de recursos
Uma vinculação de função condicional pode ser usada para conceder acesso a participantes de recursos com nomes que correspondam a um prefixo, como instâncias de máquina virtual (VM) do Compute Engine com nomes que começam com uma determinada string. O prefixo do nome do recurso é normalmente usado para agrupar recursos destinados a determinadas finalidades ou que têm propriedades específicas.
Por exemplo, imagine que você execute cargas de trabalho em determinadas instâncias de VM que
possam operar em dados sensíveis de saúde. Outras cargas de trabalho não sensíveis precisam ser executadas
no mesmo projeto, e você quer garantir que os desenvolvedores tenham acesso limitado
a instâncias de VM que operam em dados sensíveis. Para atingir essa meta,
nomeie as instâncias de VM com dados sensíveis com um prefixo sensitiveAccess
e outras
instâncias de VM com um prefixo devAccess
. Em seguida, use as vinculações de papel condicionais
para garantir que os desenvolvedores possam continuar produtivos com instâncias de VM devAccess
normais, mas sem conceder a eles acesso a instâncias de VM sensitiveAccess
.
É possível usar só o atributo de condição resource.name
para gerenciar o acesso, mas é comum usar os atributos resource.type
e resource.service
. Ao usar esses outros atributos, é menos provável que uma condição afete o acesso a diferentes tipos de recursos com nomes semelhantes.
O exemplo nesta seção controla o acesso usando os atributos resource.name
e resource.type
.
Para conceder acesso com base em um prefixo de nome para discos e instâncias do Compute Engine em um projeto:
Console
No console do Google Cloud , acesse a página IAM.
Na lista de participantes, localize o participante desejado e clique no botão
.No painel Editar permissões, localize o papel desejado para configurar uma condição. Em seguida, em Condição do IAM (opcional), clique em Adicionar condição do IAM.
No painel Editar condição, insira um título e uma descrição opcional para a condição.
É possível adicionar uma expressão de condição usando o Criador de condições ou o Editor da condição. O criador de condições fornece uma interface interativa para selecionar o tipo de condição desejado, o operador e outros detalhes aplicáveis sobre a expressão. O editor da condição fornece uma interface baseada em texto para inserir manualmente uma expressão usando a sintaxe CEL.
Criador de condições:
- Exclua todos os campos de condição do criador de condições. O único campo no criador de condições é o botão Adicionar.
- Crie uma expressão de condição agrupada que seja avaliada como
true
se o recurso for um disco que começa com o prefixo especificado:- Clique no menu suspenso Adicionar e em Condições agrupadas.
- Na lista suspensa Tipo de condição, selecione Recurso > Tipo.
- Na lista suspensa Operador, selecione é.
- Na lista suspensa Tipo de recurso, selecione compute.googleapis.com/Disk.
- Clique no primeiro botão Adicionar logo abaixo da condição que você acabou de inserir para adicionar outra cláusula à expressão.
- Na lista suspensa Tipo de condição, selecione Recurso > Nome.
- Na lista suspensa Operador, selecione Começa com.
- No campo Valor, insira o nome do
recurso,
incluindo o prefixo desejado, no formato apropriado. Por exemplo,
use
projects/PROJECT_ID/region/ZONE_ID/disks/PREFIX
para identificar discos no projetoPROJECT_ID
e na zonaZONE_ID
cujos nomes começam comPREFIX
. - À esquerda de cada tipo de condição, clique em E para garantir que as duas cláusulas sejam verdadeiras.
- Crie uma expressão de condição agrupada que seja avaliada como
true
se o recurso for uma instância que começa com o prefixo especificado:- Clique no botão Adicionar fora do grupo de condições atual e em Condições agrupadas.
- Na lista suspensa Tipo de condição, selecione Recurso > Tipo.
- Na lista suspensa Operador, selecione é.
- Na lista suspensa Tipo de recurso, selecione compute.googleapis.com/Instance.
- No mesmo grupo de condições, clique em Adicionar.
- Na lista suspensa Tipo de condição, selecione Recurso > Nome.
- Na lista suspensa Operador, selecione Começa com.
- No campo Valor, insira o nome do
recurso com o prefixo desejado no formato apropriado. Por exemplo, use
projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX
para identificar instâncias no projetoPROJECT_ID
e na zonaZONE_ID
cujos nomes começam comPREFIX
. - Verifique se o operador lógico que conecta as condições no grupo está definido como E.
- Crie uma expressão de condição agrupada que seja avaliada como
true
se o recurso não for um disco ou uma instância:- Clique no botão Adicionar fora dos grupos de condições atuais e em Condições agrupadas.
- Na lista suspensa Tipo de condição, selecione Recurso > Tipo.
- Na lista suspensa Operador, selecione não é.
- Na lista suspensa Tipo de recurso, selecione compute.googleapis.com/Disk.
- No mesmo grupo de condições, clique em Adicionar.
- Na lista suspensa Tipo de condição, selecione Recurso > Tipo.
- Na lista suspensa Operador, selecione não é.
- Na lista suspensa Tipo de recurso, selecione compute.googleapis.com/Instance.
- Verifique se o operador lógico que conecta as condições no grupo está definido como E.
Confira se o operador lógico que conecta todos os grupos de expressões de condição é Or.
Quando terminar, o criador de condições vai ficar parecido com este:
Clique em Salvar para aplicar a condição.
Depois que o painel Editar condição for fechado, clique em Salvar novamente no painel Editar permissões para atualizar a política de permissão.
Editor de condições:
Clique na guia Editor da condição e digite a seguinte expressão:
(resource.type == "compute.googleapis.com/Disk" && resource.name.startsWith("projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX")) || (resource.type == "compute.googleapis.com/Instance" && resource.name.startsWith("projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX")) || (resource.type != "compute.googleapis.com/Disk" && resource.type != "compute.googleapis.com/Instance")
Depois de inserir a expressão, é possível inspecionar a sintaxe CEL clicando em Executar linter acima da caixa de texto na parte superior direita.
Clique em Salvar para aplicar a condição.
Quando o painel Editar condição for fechado, clique em Salvar novamente no painel Editar permissões para atualizar a política do IAM.
gcloud
As políticas de permissão são definidas usando o padrão read-modify-write.
Execute o comando gcloud projects get-iam-policy
para descobrir a política atual de permissão para o projeto. No exemplo a seguir,
a versão JSON da política de permissão é transferida por download para um caminho no disco.
Comando:
gcloud projects get-iam-policy project-id --format=json > filepath
É feito o download da política de permissão no formato JSON:
{
"bindings": [
{
"members": [
"user:[email protected]"
],
"role": "roles/owner"
},
{
"members": [
"group:[email protected]"
],
"role": "roles/compute.instanceAdmin"
}
],
"etag": "BwWKmjvelug=",
"version": 1
}
Para configurar a política com uma condição de prefixo de nome de recurso, adicione a seguinte expressão de condição destacada. A CLI gcloud atualiza a versão automaticamente:
{ "bindings": [ { "members": [ "user:[email protected]" ], "role": "roles/owner" }, { "members": [ "group:[email protected]" ], "role": "roles/compute.instanceAdmin", "condition": { "title": "PREFIX_only", "description": "Only gives access to VMs with the PREFIX prefix", "expression": "(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX')) || (resource.type != 'compute.googleapis.com/Instance' && resource.type != 'compute.googleapis.com/Disk')" } } ], "etag": "BwWKmjvelug=", "version": 3 }
Em seguida, execute o comando gcloud projects set-iam-policy
para definir a nova política:
gcloud projects set-iam-policy project-id filepath
A nova vinculação de papel condicional concede as permissões do grupo da seguinte maneira:
- Os membros na vinculação de função só podem usar permissões de disco e instância para acessar discos e instâncias com nomes que começam com o prefixo especificado
- Os membros na vinculação de função podem usar todas as outras permissões no papel de administrador de instâncias (
roles/compute.instanceAdmin
) para acessar todos os recursos, exceto discos e instâncias.
REST
Use o padrão read-mod-write para permitir o acesso a recursos específicos.
Primeiro, leia a política de permissão para o projeto:
O método projects.getIamPolicy
da API Resource Manager recebe a política do IAM de um projeto.
Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:
PROJECT_ID
: o ID do projeto do Google Cloud . Os IDs do projeto são strings alfanuméricas, comomy-project
.POLICY_VERSION
: a versão da política a ser retornada. As solicitações precisam especificar a versão mais recente da política, que é a versão 3 da política. Para saber mais detalhes, consulte Como especificar uma versão da política ao receber uma política.
Método HTTP e URL:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:getIamPolicy
Corpo JSON da solicitação:
{ "options": { "requestedPolicyVersion": POLICY_VERSION } }
Para enviar a solicitação, expanda uma destas opções:
Você receberá uma resposta JSON semelhante a esta:
{ "version": 1, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:[email protected] ] }, { "members": [ "group:[email protected]" ], "role": "roles/compute.instanceAdmin" } ] }
Em seguida, modifique a política para permitir o acesso a recursos específicos. Altere o campo version
para o valor
3
:
{ "version": 3, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:[email protected]" ] }, { "role": "roles/compute.instanceAdmin", "members": [ "group:[email protected]" ], "condition": { "title": "PREFIX_only", "description": "Only gives access to VMs with the PREFIX prefix", "expression": "(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX')) || (resource.type != 'compute.googleapis.com/Instance' && resource.type != 'compute.googleapis.com/Disk')" } } ] }
Por fim, escreva a política de permissão atualizada:
O método projects.setIamPolicy
da API Resource Manager define a política na solicitação como a nova política do IAM do projeto.
Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:
PROJECT_ID
: o ID do projeto do Google Cloud . Os IDs do projeto são strings alfanuméricas, comomy-project
.
Método HTTP e URL:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy
Corpo JSON da solicitação:
{ "policy": { "version": 3, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:[email protected]" ] }, { "role": "roles/compute.instanceAdmin", "members": [ "group:[email protected]" ], "condition": { "title": "Dev_access_only", "description": "Only access to devAccess* VMs", "expression": "(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX')) || (resource.type != 'compute.googleapis.com/Instance' && resource.type != 'compute.googleapis.com/Disk')" } } ] } }
Para enviar a solicitação, expanda uma destas opções:
A resposta contém a política de permissão atualizada.
Extrair valores de nomes de recursos
Os exemplos anteriores mostram comparações booleanas entre o nome do recurso ou o início do nome do recurso e outro valor. Em alguns casos, talvez seja necessário comparar um valor com uma parte específica do nome do recurso que não esteja no início do nome.
É possível usar a função extract()
e especificar um modelo de extração para extrair a parte relevante do nome do recurso como uma string. Se necessário, é possível converter a string extraída em outro tipo, como um carimbo de data/hora. Depois de extrair um valor do nome do recurso, é possível comparar esse valor com outros valores.
Os exemplos a seguir mostram expressões de condição que usam a
função extract()
. Para detalhes sobre a função extract()
, consulte a
referência do atributo Condições do IAM.
Exemplo: fazer a correspondência de pedidos dos últimos 30 dias
Suponha que você armazene informações de pedidos em vários buckets do Cloud Storage e que os objetos em cada bucket estejam organizados por data. Um nome de objeto típico pode ser semelhante a este exemplo:
projects/_/buckets/acme-orders-aaa/objects/data_lake/orders/order_date=2019-11-03/aef87g87ae0876
Você quer permitir que um diretor acesse qualquer pedido dos últimos 30 dias. A
condição a seguir corresponde aos objetos do Cloud Storage desses pedidos. Ela usa as funções duration()
e date()
para subtrair 30 dias (2.592.000 segundos) do tempo de solicitação e comparar esse carimbo de data/hora com a data do pedido:
resource.type == 'storage.googleapis.com/Object' &&
request.time - duration('2592000s') < date(resource.name.extract('/order_date={date_str}/'))
Para detalhes sobre as funções date()
e duration()
, consulte a referência do atributo de data/hora.
Exemplo: fazer a correspondência de VMs do Compute Engine em qualquer local
Suponha que você queira conceder um papel no nível do projeto a um diretor para qualquer
VM do Compute Engine com um nome que comece com dev-
, independentemente do local
da VM. Você também quer que o diretor possa usar esse papel para todos os outros tipos de recursos.
O nome do recurso para uma VM usa um formato semelhante a projects/PROJECT_ID/zones/ZONE_ID/instances/INSTANCE_ID
.
A condição a seguir é avaliada como true
para VMs com um nome de instância que
começa com a string dev-
e para todos os tipos de recursos, exceto VMs:
resource.type != 'compute.googleapis.com/Instance' ||
resource.name.extract('/instances/{name}').startsWith('dev-')
O texto entre chaves identifica a parte do nome do recurso que é extraída para comparação. Neste exemplo, o modelo de extração retira todos os caracteres após a primeira ocorrência da string /instances/
.
Considerações importantes sobre o uso de condições baseadas em recursos
Ao adicionar uma condição baseada em recurso, é importante considerar como a condição afetará as permissões do participante.
Papéis personalizados
Considere o exemplo a seguir, que envolve papéis
personalizados. Um administrador quer criar um
papel personalizado que concede acesso para criar instâncias de VM, mas só permite que o usuário
crie instâncias de VM em um projeto com um nome de recurso que comece com o
prefixo de nome staging
, usando os discos com o mesmo prefixo de nome.
Para atingir essa meta, verifique se o papel concedido contém as permissões necessárias para criar uma instância de VM, o que significa permissões em tipos de recurso de instância e disco. Em seguida, confirme se a expressão de condição verifica o nome do recurso para ambos: discos e instâncias. Além desses dois tipos, outras permissões no papel não são concedidas.
A seguinte expressão de condição resultará em um comportamento inesperado. As permissões para operar em VMs do Compute Engine estão bloqueadas:
resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/staging')
A expressão de condição a seguir inclui discos e instâncias e controlará o acesso com base no nome do recurso para esses dois tipos:
(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/staging')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/staging'))
A expressão de condição a seguir inclui discos e instâncias e controlará o acesso com base no nome do recurso para esses dois tipos. Para qualquer outro tipo de recurso, a expressão de condição concederá o papel independentemente do nome do recurso:
(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/staging')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/staging')) || (resource.type != 'compute.googleapis.com/Disk' && resource.type != 'compute.googleapis.com/Instance')
Permissões somente para pai
Na hierarquia de recursos do Google Cloud, algumas das permissões em um papel
que afetam um recurso filho precisam ser aplicadas somente no nível pai. Por exemplo, para listar projetos em uma organização, um usuário precisa receber
a permissão resourcemanager.projects.list
na organização cujos
projetos ele quer listar, e não nos próprios projetos. Esses tipos de
permissões são chamados de permissões somente para pai e se aplicam apenas a operações
list
.
Para conceder acesso adequadamente às permissões *.*.list
ao usar condições, a expressão de condição deve definir os atributos resource.service
e resource.type
de acordo com o tipo de recurso pai dos recursos de destino a serem listados.
Veja estes exemplos. Usando o exemplo do Compute Engine da
seção anterior, a expressão a seguir impede o acesso às
permissões compute.disks.list
e compute.instances.list
porque o
recurso em que essas permissões são verificadas tem o valor de atributo resource.type
de cloudresourcemanager.googleapis.com/Project
.
(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX'))
É comum que essas permissões list
sejam concedidas com outras permissões para operações regulares no recurso. Para aumentar o escopo da permissão nesse caso, estenda o escopo somente para o tipo cloudresourcemanager.googleapis.com/Project
ou o escopo para todas as outras permissões que não sejam do tipo instância ou disco.
(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX')) || resource.type == 'cloudresourcemanager.googleapis.com/Project'
ou
(resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/PREFIX')) || (resource.type == 'compute.googleapis.com/Instance' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/instances/PREFIX')) || (resource.type != 'compute.googleapis.com/Disk' && resource.type != 'compute.googleapis.com/Instance')