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
No Google Cloud Console, acesse a seção IAM & Admin > Service Accounts.
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.
Anote o email da SA Ponte (ex.:
[email protected]).Gere uma chave JSON para esta SA e armazene-a.
Crie as demais SAs que serão impersonificadas. Estas SAs serão tratadas nesta documentação como SAs alvo.
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
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
O BigQuery permite até 400 RAPs por tabela.
Para contornar essa limitação:
Aplicamos subqueries em cada RAP, usando a tabela de permissões.
Assim, podemos filtrar até 399 campos diferentes.
Mantemos 1 RAP reservada para a política de full access (quando o usuário precisa visualizar todos os dados sem restrições).
Lembre-se que após criar RAPs em uma tabela, apenas usuários que estão contemplados por elas conseguem acessar os dados. Com isso, SEMPRE crie uma RAP de full access para quem for pertinente.
CREATE OR REPLACE ROW ACCESS POLICY full_access_policy
ON `projeto.dataset.tabela_vendas`
GRANT TO ("user:[email protected]")
FILTER USING (
TRUE
)
);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?