Esta página descreve como gerir o acesso a recursos específicos através de associações de funções condicionais nas suas políticas de autorização. Ao usar resource attributes numa expressão de condição, pode controlar se um principal pode usar uma autorização para aceder a um recurso com base no nome, no tipo e no Google Cloud serviço do recurso.
Antes de começar
- Leia a vista geral das condições da gestão de identidade e de acesso (IAM) para compreender as noções básicas das associações de funções condicionais da IAM.
- Reveja os atributos de recursos que podem ser usados numa expressão de condição.
- O atributo do nome do recurso pode controlar o acesso aos
seguintes Google Cloud serviços:
- Apigee
- Application Integration
- Apigee API Hub
- Serviço de cópia de segurança e RD
- 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
- Integration Connectors
- Google Cloud Managed Service para Apache Kafka
- Gestor de parâmetros
- Pub/Sub Lite
- Secret Manager
- Spanner
Funções necessárias
Para receber as autorizações de que precisa para gerir as associações de funções condicionais, peça ao seu administrador que lhe conceda as seguintes funções do IAM:
-
Para gerir o acesso a projetos:
Administrador de IAM do projeto (
roles/resourcemanager.projectIamAdmin
) no projeto -
Para gerir o acesso a pastas:
Administrador da pasta (
roles/resourcemanager.folderAdmin
) na pasta -
Para gerir o acesso a projetos, pastas e organizações:
Administrador da organização (
roles/resourcemanager.organizationAdmin
) na organização -
Para gerir o acesso a quase todos os Google Cloud recursos:
Administrador de segurança (
roles/iam.securityAdmin
) no projeto, na pasta ou na organização cujos recursos quer gerir o acesso
Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.
Estas funções predefinidas contêm as autorizações necessárias para gerir associações de funções condicionais. Para ver as autorizações exatas que são necessárias, expanda a secção Autorizações necessárias:
Autorizações necessárias
As seguintes autorizações são necessárias para gerir associações de funções condicionais:
-
Para gerir o acesso a projetos:
-
resourcemanager.projects.getIamPolicy
no projeto -
resourcemanager.projects.setIamPolicy
no projeto
-
-
Para gerir o acesso a pastas:
-
resourcemanager.folders.getIamPolicy
na pasta -
resourcemanager.folders.setIamPolicy
na pasta
-
-
Para gerir o acesso a organizações:
-
resourcemanager.organizations.getIamPolicy
na organização -
resourcemanager.organizations.setIamPolicy
na organização
-
Também pode conseguir estas autorizações com funções personalizadas ou outras funções predefinidas.
Conceda acesso a um grupo de recursos com base nos prefixos dos nomes dos recursos
Uma associação de funções condicional pode ser usada para conceder acesso a responsáveis por recursos cujos nomes de recursos correspondam a um prefixo, como instâncias de máquinas virtuais (VM) do Compute Engine cujos nomes comecem por uma determinada string. Normalmente, o prefixo do nome do recurso é usado para agrupar recursos destinados a um determinado fim ou que têm determinadas propriedades.
Por exemplo, imagine que executa cargas de trabalho em determinadas instâncias de VM que podem operar em dados de saúde confidenciais. Outras cargas de trabalho não confidenciais têm de ser executadas no mesmo projeto, e quer garantir que os seus programadores têm acesso limitado a instâncias de VMs que operam em dados confidenciais. Para atingir este objetivo,
atribui nomes às instâncias de VM sensíveis a dados com o prefixo sensitiveAccess
e às outras
instâncias de VM com o prefixo devAccess
. Em seguida, usa associações de funções condicionais
para garantir que os programadores podem manter a produtividade com instâncias de devAccess
VM
normais, mas sem lhes conceder acesso a instâncias de sensitiveAccess
VM.
Embora possa usar o atributo de condição resource.name
sozinho para gerir o acesso, é comum usar também os atributos resource.type
e resource.service
. Quando usa estes atributos adicionais, torna menos provável que uma condição afete o acesso a diferentes tipos de recursos com nomes semelhantes.
O exemplo nesta secção controla o acesso através dos atributos resource.name
e resource.type
.
Para conceder acesso com base num prefixo de nome a discos e instâncias do Compute Engine num projeto:
Consola
Na Google Cloud consola, aceda à página IAM.
Na lista de diretores, localize o diretor pretendido e clique no botão
.No painel Editar autorizações, localize a função pretendida 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, introduza um título e uma descrição opcional para a condição.
Pode adicionar uma expressão de condição através do Criador de condições ou do Editor de condições. O criador de condições oferece uma interface interativa para selecionar o tipo de condição, o operador e outros detalhes aplicáveis sobre a expressão pretendidos. O editor de condições oferece uma interface baseada em texto para introduzir manualmente uma expressão com a sintaxe do IEC.
Construtor de condições:
- Elimine todos os campos de condições existentes do criador de condições. O único campo no criador de condições deve ser o botão Adicionar.
- Crie uma expressão de condição agrupada que seja avaliada como
true
se o recurso for um disco que comece pelo prefixo especificado:- Clique no menu pendente Adicionar e, de seguida, clique em Condições agrupadas.
- No menu pendente Tipo de condição, selecione Recurso > Tipo.
- No menu pendente Operador, selecione é.
- No menu pendente Tipo de recurso, selecione compute.googleapis.com/Disk.
- Clique no primeiro botão Adicionar imediatamente abaixo da condição que acabou de introduzir para adicionar outra cláusula à expressão.
- No menu pendente Tipo de condição, selecione Recurso > Nome.
- No menu pendente Operador, selecione Começa por.
- No campo Valor, introduza o nome
do recurso,
incluindo o prefixo pretendido, no formato adequado. 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 porPREFIX
. - À esquerda de cada tipo de condição, clique em E para garantir que ambas as cláusulas têm de ser verdadeiras.
- Crie uma expressão de condição agrupada que seja avaliada como
true
se o recurso for uma instância que comece pelo prefixo especificado:- Clique no botão Adicionar fora do grupo de condições existente e, de seguida, clique em Condições agrupadas.
- No menu pendente Tipo de condição, selecione Recurso > Tipo.
- No menu pendente Operador, selecione é.
- No menu pendente Tipo de recurso, selecione compute.googleapis.com/Instance.
- No mesmo grupo de condições, clique em Adicionar.
- No menu pendente Tipo de condição, selecione Recurso > Nome.
- No menu pendente Operador, selecione Começa por.
- No campo Valor, introduza o nome
do recurso,
com o prefixo pretendido, no formato adequado. 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 porPREFIX
. - Certifique-se de que o operador lógico que liga 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 existentes e, de seguida, clique em Condições agrupadas.
- No menu pendente Tipo de condição, selecione Recurso > Tipo.
- No menu pendente Operador, selecione não é.
- No menu pendente Tipo de recurso, selecione compute.googleapis.com/Disk.
- No mesmo grupo de condições, clique em Adicionar.
- No menu pendente Tipo de condição, selecione Recurso > Tipo.
- No menu pendente Operador, selecione não é.
- No menu pendente Tipo de recurso, selecione compute.googleapis.com/Instance.
- Certifique-se de que o operador lógico que liga as condições no grupo está definido como E.
Certifique-se de que o operador lógico que liga todos os grupos de expressões de condição é Or.
Quando terminar, o criador de condições deve ter um aspeto semelhante ao seguinte:
Clique em Guardar para aplicar a condição.
Depois de fechar o painel Editar condição, clique novamente em Guardar no painel Editar autorizações para atualizar a sua política de permissão.
Editor de condições:
Clique no separador Editor de condições e introduza 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 introduzir a expressão, pode optar por validar a sintaxe CEL clicando em Executar validador acima da caixa de texto na parte superior direita.
Clique em Guardar para aplicar a condição.
Quando o painel Editar condição estiver fechado, clique novamente em Guardar no painel Editar autorizações para atualizar a política de permissão.
gcloud
As políticas de permissão são definidas através do padrão read-modify-write.
Execute o comando gcloud projects get-iam-policy
para obter a política de permissão atual do projeto. No exemplo
seguinte, a versão JSON da política de permissão é transferida para um caminho no disco.
Comando:
gcloud projects get-iam-policy project-id --format=json > filepath
O formato JSON da política de autorização é transferido:
{
"bindings": [
{
"members": [
"user:my-user@example.com"
],
"role": "roles/owner"
},
{
"members": [
"group:my-group@example.com"
],
"role": "roles/compute.instanceAdmin"
}
],
"etag": "BwWKmjvelug=",
"version": 1
}
Para configurar a política de permissão com uma condição de prefixo do nome do recurso, adicione a expressão de condição realçada seguinte. A CLI gcloud atualiza a versão automaticamente:
{ "bindings": [ { "members": [ "user:my-user@example.com" ], "role": "roles/owner" }, { "members": [ "group:my-group@example.com" ], "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, defina a nova política de permissão executando o comando
gcloud projects set-iam-policy
:
gcloud projects set-iam-policy project-id filepath
A nova associação de funções condicional concede autorizações ao grupo da seguinte forma:
- Os membros na associação de funções só podem usar autorizações de disco e instância para aceder a discos e instâncias cujos nomes comecem pelo prefixo especificado
- Os membros na associação de funções podem usar todas as outras autorizações na função de administrador da instância (
roles/compute.instanceAdmin
) para aceder a todos os recursos, exceto discos e instâncias
REST
Use o padrão read-modify-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 obtém a política de autorização de um projeto.
Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:
PROJECT_ID
: O ID do seu Google Cloud projeto. Os IDs dos projetos são strings alfanuméricas, comomy-project
.POLICY_VERSION
: a versão da política a ser devolvida. Os pedidos devem especificar a versão da política mais recente, que é a versão 3 da política. Consulte o artigo Especificar uma versão da política ao obter uma política para ver detalhes.
Método HTTP e URL:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:getIamPolicy
Corpo JSON do pedido:
{ "options": { "requestedPolicyVersion": POLICY_VERSION } }
Para enviar o seu pedido, expanda uma destas opções:
Deve receber uma resposta JSON semelhante à seguinte:
{ "version": 1, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:my-user@example.com ] }, { "members": [ "group:my-group@example.com" ], "role": "roles/compute.instanceAdmin" } ] }
Em seguida, modifique a política de permissão para que permita o acesso a recursos específicos. Certifique-se de que altera o campo version
para o valor
3
:
{ "version": 3, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:my-user@example.com" ] }, { "role": "roles/compute.instanceAdmin", "members": [ "group:my-group@example.com" ], "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 último, escreva a política de permissão atualizada:
O método projects.setIamPolicy
da API Resource Manager define a política de autorização no pedido como a nova política de autorização do projeto.
Antes de usar qualquer um dos dados do pedido, faça as seguintes substituições:
PROJECT_ID
: O ID do seu Google Cloud projeto. Os IDs dos projetos são strings alfanuméricas, comomy-project
.
Método HTTP e URL:
POST https://cloudresourcemanager.googleapis.com/v1/projects/PROJECT_ID:setIamPolicy
Corpo JSON do pedido:
{ "policy": { "version": 3, "etag": "BwWKmjvelug=", "bindings": [ { "role": "roles/owner", "members": [ "user:my-user@example.com" ] }, { "role": "roles/compute.instanceAdmin", "members": [ "group:my-group@example.com" ], "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 o seu pedido, expanda uma destas opções:
A resposta contém a política de permissão atualizada.
Extraia 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. No entanto, em alguns casos, pode ter de comparar um valor com uma parte específica do nome do recurso que não se encontra no início do nome.
Pode 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, pode converter a string extraída noutro tipo, como uma data/hora. Depois de extrair um valor do nome do recurso, pode comparar esse valor com outros valores.
Os exemplos seguintes mostram expressões de condição que usam a função extract()
. Para ver detalhes sobre a função extract()
, consulte a referência de atributos das condições do IAM.
Exemplo: fazer corresponder encomendas dos últimos 30 dias
Suponhamos que armazena informações de encomendas em vários contentores do Cloud Storage e que os objetos em cada contentor estão organizados por data. Um nome de objeto típico pode ter um aspeto semelhante ao deste exemplo:
projects/_/buckets/acme-orders-aaa/objects/data_lake/orders/order_date=2019-11-03/aef87g87ae0876
Quer permitir que um principal aceda a qualquer encomenda dos últimos 30 dias. A condição seguinte corresponde aos objetos do Cloud Storage para estas encomendas. Usa as funções duration()
e date()
para subtrair 30 dias (2 592 000 segundos) à hora do pedido e, em seguida, compara essa 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 ver detalhes sobre as funções date()
e duration()
, consulte a
referência de atributos de data/hora.
Exemplo: corresponder a VMs do Compute Engine em qualquer localização
Suponhamos que quer conceder uma função ao nível do projeto a um principal para qualquer VM do Compute Engine cujo nome comece por dev-
, independentemente da localização da VM. Também quer que o principal possa usar essa função para todos os outros tipos de recursos.
O nome do recurso de uma VM usa um formato semelhante a
projects/PROJECT_ID/zones/ZONE_ID/instances/INSTANCE_ID
.
A condição seguinte é avaliada como true
para VMs com um nome de instância que começa pela string dev-
e para todos os tipos de recursos que não sejam VMs:
resource.type != 'compute.googleapis.com/Instance' ||
resource.name.extract('/instances/{name}').startsWith('dev-')
O texto entre chavetas identifica a parte do nome do recurso que é
extraída para comparação. Neste exemplo, o modelo de extração extrai todos os carateres após a primeira ocorrência da string /instances/
.
Considerações de utilização importantes para condições baseadas em recursos
Quando adiciona uma condição baseada em recursos, é importante considerar como a condição afeta as autorizações do principal.
Funções personalizadas
Considere o seguinte exemplo, que envolve funções
personalizadas. Um administrador quer criar uma função personalizada que conceda acesso para criar instâncias de VM, mas apenas permite que o utilizador crie instâncias de VM num projeto com um nome de recurso que comece pelo prefixo de nome staging
, usando os discos com o mesmo prefixo de nome.
Para atingir este objetivo, certifique-se de que a função concedida contém as autorizações necessárias para criar uma instância de VM, o que significa autorizações nos tipos de recursos de disco e de instância. Em seguida, certifique-se de que a expressão de condição verifica o nome do recurso para ambos os discos e as instâncias. Além destes dois tipos, não são concedidas outras autorizações na função.
A seguinte expressão de condição vai resultar num comportamento inesperado. As autorizaçõ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 seguinte expressão de condição inclui discos e instâncias e vai gerir o acesso com base no nome do recurso para estes 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 seguinte inclui discos e instâncias e vai gerir o acesso com base no nome do recurso para estes dois tipos. Para qualquer outro tipo de recurso, a expressão de condição concede a função 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')
Autorizações apenas para pais
Na hierarquia de recursos do Google Cloud, algumas das autorizações numa função que afetam um recurso secundário destinam-se a ser aplicadas apenas ao nível principal. Por exemplo, para listar projetos numa organização, um utilizador tem de ter a autorização resourcemanager.projects.list
na organização cujos projetos quer listar e não nos próprios projetos. Estes tipos de
autorizações são denominados autorizações apenas para o pai e aplicam-se apenas a list
operações.
Para conceder corretamente acesso às autorizações *.*.list
quando 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 principal dos recursos de destino a listar.
Considere os seguintes exemplos. Usando o exemplo do Compute Engine da secção anterior, a seguinte expressão impede o acesso às autorizações compute.disks.list
e compute.instances.list
, uma vez que o recurso no qual estas autorizações são verificadas tem o valor do 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 estas autorizações list
sejam concedidas juntamente com outras autorizações para operações normais no recurso. Para aumentar o âmbito da concessão neste caso, pode alargar o âmbito apenas para o tipo cloudresourcemanager.googleapis.com/Project
ou alargar o âmbito a todas as outras autorizaçõ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')