Configurando a impersonificação de Service Accounts

Neste modelo de impersonificação, uma Service Account é configurada para agir em nome de outras Service Accounts.

1. Criação das Service Accounts

1.1. Criação das Service Accounts

  1. No Google Cloud Console, acesse a seção IAM & Admin > Service Accounts.

  2. Crie uma nova SA dedicada, para servir como uma ponte entre a aplicação e as demais SAs que serão criadas para uso na execução das consultas no BigQuery. Essa SA será tratada nesta documentação como SA Ponte.

  3. Anote o email da SA Ponte (ex.: [email protected]).

  4. Gere uma chave JSON para esta SA e armazene-a.

  5. Crie as demais SAs que serão impersonificadas. Estas SAs serão tratadas nesta documentação como SAs alvo.

  6. Anote email destas SAs (ex: [email protected])

1.2. Concessão de Permissões às SAs no Projeto Alvo

Garanta que as SAs possuam os papéis mínimos necessários no BigQuery:

  • Nível IAM:

    • bigquery.jobs.create

    • bigquery.readsessions.create

    • bigquery.readsessions.getData

  • Nível do Dataset (Leitura):

    • bigquery.datasets.get

    • bigquery.jobs.create

    • bigquery.tables.get

    • bigquery.tables.getData

    • bigquery.tables.list

Atribua as mesmas permissões a nível do Dataset par a SA Ponte, caso queira que ela também possa ser utilizada para realizar consultas no BigQuery.

1.3. Permitindo que a SA Ponte impersonifique a SA Alvo

Para que o mecanismo funcione, a SA Ponte precisa ter o papel roles/iam.serviceAccountTokenCreator sobre a SA alvo. Para isto, pode-se executar o seguinte comando do gcloud:

gcloud iam service-accounts add-iam-policy-binding {email da SA alvo} \
  --member="serviceAccount:{email da SA ponte}" \
  --role="roles/iam.serviceAccountTokenCreator"

2. Criação das Row Access Policies (RAPs)

2.1. Cadastro da Tabela de Segurança

Crie uma tabela dedicada para armazenar permissões por Service Account.

A coluna principal (usuário) precisa conter os mesmos emails que estão contidos nas SAs alvo que foram criadas no passo 1.1.

Exemplo de tabela (tabela_permissionamento):

Essa tabela será utilizada nas subqueries dentro das RAPs para verificar permissões de acesso.

2.2. Criação das Row Access Policies

Com base na tabela de segurança, criamos as RAPs utilizando subqueries.

Exemplo de RAP em tabela_vendas:

CREATE OR REPLACE ROW ACCESS POLICY loja_policy
ON `projeto.dataset.tabela_vendas`
GRANT TO (
"serviceAccount:sa-ponte-impersonalization@looqbox-development.iam.gserviceaccount.com",
"allAuthenticatedUsers"
)
FILTER USING (
  loja_id IN (
    SELECT loja_id
    FROM `project.dataset.tabela_permissionamento`
    WHERE usuario = SESSION_USER()
  )
);

Esse padrão pode ser replicado para cada campo que precisa de filtro: loja_id, regional_id, categoria_id, etc.

No exemplo, utiliza-se a GRANT allAuthenticatedUsers para que não seja necessário realizar modificações na RAP conforme os acessos sejam concedidos ou revogados. Ou seja, desde que o usuário ou SA esteja ativa, serão contemplados pelo GRANT. Entretanto só terá acesso aos dados se estiver presente na tabela de permissionamento.

Ao configurar os GRANTS, podemos informar os seguintes valores:

  • user:{email do usuário do GCP}

  • group:{grupo de email do GCP}

  • domain:{Domínio do GCP}

  • serviceAccount:{email da service account}

  • allAuthenticathedUsers

Para exemplos de como como configurar as grants, acesse a documentação oficial do GCP

3. Exemplos de Testes

Após configurar as RAPs e a tabela de segurança, é possível realizar testes de personificação para validar os acessos.

Para os testes, podemos utilizar o seguinte snippet de código em Python, variando apenas o valor passado na linha 14

from google.oauth2 import service_account
from google.auth import impersonated_credentials
from google.cloud import bigquery

# Carrega a chave da SA Ponte
source_credentials = service_account.Credentials.from_service_account_file(
    filename="{caminho_para_json_sa_ponte}.json",
    scopes=["https://www.googleapis.com/auth/bigquery"]
)

# Cria credenciais impersonando a SA alvo
impersonated_creds = impersonated_credentials.Credentials(
    source_credentials=source_credentials,
    target_principal="{email_da_sa_alvo}",
    target_scopes=["https://www.googleapis.com/auth/bigquery"],
    lifetime=3600  # TTL do token em segundos (1h)
)

# Agora você usa impersonated_creds no cliente BigQuery
client = bigquery.Client(
    credentials=impersonated_creds,
    project="{project_id_da_tabela}"
    )

query = """
    SELECT
    *
    FROM `projeto.dataset.tabela_vendas`
    """
query_job = client.query(query=query)
data = query_job.to_dataframe()
print(data)

Teste 1 – Usuário com acesso limitado a loja L001

target_principal="[email protected]"

Consulta:

-- Impersonando o usuario 1
SELECT *
FROM `projeto.dataset.tabela_vendas`

✅ Retorna apenas registros da loja L001.


Teste 2 – Usuário com acesso limitado a loja L002

target_principal="sa-user02-impersonalization@looqbox-development.iam.gserviceaccount.com"

Consulta:

-- Impersonando o usuario 2
SELECT *
FROM `projeto.dataset.tabela_vendas`

✅ Retorna apenas registros da loja L002.


Teste 3 – Usuário sem acesso

target_principal="sa-user04-impersonalization@looqbox-development.iam.gserviceaccount.com"

Consulta:

-- Impersonando o usuario 4
SELECT *
FROM `projeto.dataset.tabela_vendas`

❌ Retorna zero resultados, pois o usuário não consta na tabela de permissões.


Teste 4 – Usuário com acesso total (full access)

# Agora você usa a source_credentials da SA ponte
client = bigquery.Client(
    credentials=source_credentials,
    project="{project_id_da_tabela}"
    )

Consulta:

-- Utilizando a própria SA ponte (com RAP de full access)
SELECT *
FROM `projeto.dataset.tabela_vendas`

✅ Retorna registros de todas as lojas.

Ao consultar o histórico de jobs do projeto, pode-se constatar que cada uma das queries foi, de fato, atrelada a cada uma das SAs apontadas (ou da própiria ponte):

Last updated

Was this helpful?