Fundamentação Teórica: Create and Use Shared Access Signature (SAS) Tokens
1. Intuição Inicial
Imagine que você tem um documento confidencial em um cofre e precisa que um cliente específico possa ler esse documento amanhã entre 14h e 16h, sem precisar dar a ele a combinação do cofre. Você cria uma chave temporária que abre apenas aquele documento, apenas naquele horário, e só para leitura.
Isso é exatamente um SAS Token (Shared Access Signature): uma URL assinada criptograficamente que concede acesso delegado e controlado a recursos do Azure Storage, sem expor as credenciais principais da conta.
Em vez de dar a um parceiro externo a Account Key (que daria acesso total a tudo), você gera um SAS Token que diz: "você pode ler apenas este arquivo específico, até amanhã às 16h, e apenas para leitura". Quando o prazo expira, o token deixa de funcionar automaticamente.
Na prática, SAS Tokens são o mecanismo usado para:
- Compartilhar arquivos temporariamente com usuários externos
- Permitir que aplicações façam upload de arquivos diretamente no storage sem passar por um servidor backend
- Integrar sistemas de terceiros que precisam de acesso limitado a dados específicos
2. Contexto
Onde SAS se encaixa nos mecanismos de autenticação do Azure Storage
Por que SAS Tokens existem
Account Keys são como a chave master de um prédio: dão acesso a tudo, não expiram automaticamente e são difíceis de revogar rapidamente. Compartilhar Account Keys para acesso temporário ou limitado é uma prática de segurança ruim.
RBAC do Azure AD é poderoso, mas requer que o receptor tenha uma identidade no Azure AD. Parceiros externos, aplicações móveis de usuários, ou sistemas legados frequentemente não têm essa identidade.
SAS Tokens resolvem esse problema: acesso preciso, temporário e sem necessidade de identidade Azure AD, assinado criptograficamente para garantir integridade.
3. Construção dos Conceitos
3.1 Os três tipos de SAS
Antes de entender como criar um SAS, é fundamental entender os três tipos e quando cada um se aplica:
Account SAS
Concede acesso a recursos de um ou mais serviços da storage account (Blob, File, Queue, Table). O escopo pode ser amplo (múltiplos serviços, múltiplos tipos de recurso).
Assinado com: Account Key (chave de 512 bits da storage account) Escopo: Account inteira, com filtros por serviço, recurso e operações Risco: se a Account Key for comprometida, todos os SAS Account assinados com ela devem ser considerados comprometidos
Service SAS
Concede acesso a recursos de um único serviço (apenas Blob, ou apenas File, ou apenas Queue, ou apenas Table). Mais restrito que o Account SAS.
Assinado com: Account Key Escopo: Um serviço específico, podendo ser um container, um blob específico, uma fila, uma tabela Diferencial: pode ser associado a uma Stored Access Policy, que permite revogação sem precisar regenerar a Account Key
User Delegation SAS
Concede acesso a recursos de Blob (e Data Lake Gen2). Funciona apenas para o serviço Blob.
Assinado com: Credenciais do Azure AD do usuário que gerou o token (não com Account Key) Escopo: Blob service apenas Vantagem crítica: pode ser revogado sem impactar outros SAS ou a Account Key. É o tipo mais seguro e recomendado.
3.2 Anatomia de um SAS Token
Um SAS Token é uma string de query parameters que, quando appendada à URL de um recurso do storage, define as condições de acesso. Veja um exemplo real de SAS Token para um blob:
https://stgprod001.blob.core.windows.net/container1/arquivo.pdf
?sv=2022-11-02 (signedVersion - versão da API)
&ss=b (signedServices - b=blob)
&srt=o (signedResourceTypes - o=object)
&sp=r (signedPermissions - r=read)
&se=2026-03-25T18%3A00%3A00Z (signedExpiry - data/hora de expiração)
&st=2026-03-24T10%3A00%3A00Z (signedStart - data/hora de início)
&spr=https (signedProtocol - apenas HTTPS)
&sig=abc123... (signature - assinatura HMAC-SHA256)
Cada parâmetro tem um propósito específico:
| Parâmetro | Nome | Valores possíveis |
|---|---|---|
sv | Signed Version | Versão da API de storage (ex: 2022-11-02) |
ss | Signed Services | b=Blob, f=File, q=Queue, t=Table |
srt | Signed Resource Types | s=Service, c=Container, o=Object |
sp | Signed Permissions | r=Read, w=Write, d=Delete, l=List, a=Add, c=Create, u=Update, p=Process, t=Tag, f=Filter, i=Set Immutability, x=Delete version |
se | Signed Expiry | Data/hora ISO 8601 UTC |
st | Signed Start | Data/hora ISO 8601 UTC (opcional) |
sip | Signed IP | IP ou range de IP permitido |
spr | Signed Protocol | https ou https,http |
sig | Signature | HMAC-SHA256 de todos os parâmetros |
A assinatura (sig) é o que garante a integridade: é o hash criptográfico de todos os parâmetros combinados com a Account Key ou credencial Azure AD. Se qualquer parâmetro for modificado, a assinatura não bate e a requisição é rejeitada.
3.3 Permissões por serviço
As permissões disponíveis variam por serviço:
| Permissão | Blob | File | Queue | Table |
|---|---|---|---|---|
| Read (r) | Ler blob | Ler arquivo | Ler mensagem (peek) | Ler entidades |
| Write (w) | Criar/escrever blob | Criar/escrever arquivo | N/A | Inserir/atualizar |
| Delete (d) | Deletar blob | Deletar arquivo | Deletar mensagem | Deletar entidades |
| List (l) | Listar containers/blobs | Listar diretórios/arquivos | N/A | N/A |
| Add (a) | Adicionar bloco | N/A | Adicionar mensagem | Inserir entidade |
| Create (c) | Criar blob | Criar arquivo | N/A | N/A |
| Update (u) | Atualizar blob pages | N/A | Atualizar mensagem | Mesclar entidade |
| Process (p) | N/A | N/A | Processar mensagem | N/A |
3.4 Stored Access Policies
Uma Stored Access Policy (SAP) é uma política de acesso armazenada no próprio container, fila, tabela ou file share, que pode ser referenciada por um Service SAS.
A vantagem crítica de uma SAP é a revogação centralizada: em vez de emitir um SAS com permissões e expiração hardcoded no token, você referencia uma SAP. Se precisar revogar o acesso, basta modificar ou deletar a SAP, sem precisar revogar/regenerar Account Keys.
Um SAS sem SAP é como uma chave física que não tem como ser invalidada antes de vencer. Um SAS com SAP é como um crachá eletrônico que pode ser desativado no sistema imediatamente.
4. Visão Estrutural
Fluxo de validação de um SAS Token pelo Azure Storage
Ciclo de vida de um SAS Token
5. Funcionamento na Prática
Como um SAS Account é gerado (processo técnico)
O processo de geração de um Account SAS ou Service SAS envolve:
- Construir a string-to-sign: concatenar os parâmetros em ordem específica definida pela versão da API
- Assinar com HMAC-SHA256 usando a Account Key
- Base64-encode a assinatura
- Construir a URL final com todos os parâmetros
String-to-sign para Account SAS (sv=2020-12-06 em diante):
accountName\n
signedPermissions\n
signedServices\n
signedResourceTypes\n
signedStart\n
signedExpiry\n
signedIP\n
signedProtocol\n
signedVersion\n
signedEncryptionScope\n
Cada campo vazio ainda contribui com um \n. A ordem é exata e não pode ser alterada. Qualquer modificação nos parâmetros do token na URL invalida a assinatura.
Como um User Delegation SAS é gerado
O User Delegation SAS tem um passo adicional: primeiro é necessário obter uma User Delegation Key usando as credenciais Azure AD, e então usar essa chave (não a Account Key) para assinar o SAS.
A User Delegation Key tem uma duração máxima de 7 dias, o que limita a validade máxima de qualquer User Delegation SAS.
Comportamentos não óbvios
SAS não pode ter expiração maior que a User Delegation Key. Se você gera uma User Delegation Key com validade de 2 dias e tenta criar um SAS com expiração em 5 dias, o storage rejeita na criação ou o SAS para de funcionar quando a User Delegation Key expirar.
Rotacionar Account Key invalida todos os SAS assinados com ela. Account SAS e Service SAS são assinados com a Account Key. Se você rotacionar a Account Key (key1 ou key2), todos os SAS assinados com aquela chave específica param de funcionar imediatamente. Este é o mecanismo de revogação em massa para SAS sem SAP.
SAS sem signedStart (st) é válido imediatamente.
Se você omitir o parâmetro st, o SAS é válido desde o momento da geração até se. Recomendação: defina sempre st alguns minutos no passado (para compensar diferenças de relógio entre servidores) ou omita-o com consciência.
SAS sem spr (signedProtocol) aceita HTTP e HTTPS.
Por razões de segurança, sempre especifique spr=https para forçar HTTPS. Sem esse parâmetro, o SAS Token pode ser transmitido e reutilizado via HTTP não criptografado.
SAS sem sip (signedIP) aceita qualquer IP.
Sem restrição de IP, qualquer pessoa que obtiver o token pode usá-lo de qualquer lugar até expirar.
6. Formas de Implementação
Portal do Azure
Quando usar: geração manual para compartilhamento imediato, testes, demonstrações
Gerar Account SAS (nível da Storage Account):
- Portal > Storage Account > Shared access signature (menu lateral)
- Selecionar: Allowed services (Blob, File, Queue, Table)
- Selecionar: Allowed resource types (Service, Container, Object)
- Selecionar: Allowed permissions
- Definir: Start and expiry date/time (UTC)
- Opcionalmente: Allowed IP addresses, Allowed protocols
- Selecionar: Signing key (key1 ou key2)
- Generate SAS and connection string
Gerar Service SAS (nível de container ou blob):
- Portal > Storage Account > Containers > selecionar container ou blob
- Clicar em ... (menu) > Generate SAS
- Configurar permissões, expiração, IP
- Generate SAS token and URL
Limitação: manual, não reproduzível, não escala para geração em tempo real em aplicações.
Azure CLI
# Gerar Account SAS
az storage account generate-sas \
--account-name "stgprod001" \
--account-key "<account-key>" \
--services b \
--resource-types co \
--permissions rl \
--expiry "2026-03-25T18:00:00Z" \
--start "2026-03-24T10:00:00Z" \
--https-only \
--ip "200.200.200.0/24" \
--output tsv
# Gerar Service SAS para um container específico
az storage container generate-sas \
--account-name "stgprod001" \
--account-key "<account-key>" \
--name "container1" \
--permissions rl \
--expiry "2026-03-25T18:00:00Z" \
--https-only \
--output tsv
# Gerar Service SAS para um blob específico
az storage blob generate-sas \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--name "relatorio-financeiro.pdf" \
--permissions r \
--expiry "2026-03-24T20:00:00Z" \
--https-only \
--output tsv
# Gerar URL completa (SAS + URL do blob)
SAS_TOKEN=$(az storage blob generate-sas \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--name "relatorio.pdf" \
--permissions r \
--expiry "2026-03-25T12:00:00Z" \
--https-only \
--output tsv)
BLOB_URL="https://stgprod001.blob.core.windows.net/container1/relatorio.pdf?$SAS_TOKEN"
echo "$BLOB_URL"
# Gerar User Delegation SAS (requer login com Azure AD, não Account Key)
az login # ou az login --service-principal
az storage blob generate-sas \
--account-name "stgprod001" \
--container-name "container1" \
--name "relatorio.pdf" \
--permissions r \
--expiry "2026-03-25T12:00:00Z" \
--https-only \
--auth-mode login \
--as-user \
--output tsv
# Criar Stored Access Policy em um container
az storage container policy create \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--name "policy-read-only" \
--permissions r \
--expiry "2026-12-31T23:59:59Z" \
--start "2026-01-01T00:00:00Z"
# Gerar Service SAS referenciando uma SAP
az storage container generate-sas \
--account-name "stgprod001" \
--account-key "<account-key>" \
--name "container1" \
--policy-name "policy-read-only" \
--output tsv
# Listar Stored Access Policies de um container
az storage container policy list \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--output table
# Revogar SAS: deletar a SAP
az storage container policy delete \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--name "policy-read-only"
# Revogar SAS sem SAP: rotacionar a Account Key
az storage account keys renew \
--account-name "stgprod001" \
--resource-group "rg-storage" \
--key key1
Azure PowerShell
# Configurar contexto de storage
$ctx = New-AzStorageContext `
-StorageAccountName "stgprod001" `
-StorageAccountKey "<account-key>"
# Gerar Account SAS
$accountSAS = New-AzStorageAccountSASToken `
-Context $ctx `
-Service Blob `
-ResourceType Container,Object `
-Permission "rl" `
-ExpiryTime (Get-Date).AddDays(1) `
-StartTime (Get-Date).AddMinutes(-5) `
-Protocol HttpsOnly `
-IPAddressOrRange "200.200.200.0/24"
# Gerar Service SAS para container
$containerSAS = New-AzStorageContainerSASToken `
-Context $ctx `
-Name "container1" `
-Permission "rl" `
-ExpiryTime (Get-Date).AddHours(24) `
-Protocol HttpsOnly
# Gerar Service SAS para blob específico
$blobSAS = New-AzStorageBlobSASToken `
-Context $ctx `
-Container "container1" `
-Blob "relatorio.pdf" `
-Permission "r" `
-ExpiryTime (Get-Date).AddHours(8) `
-Protocol HttpsOnly `
-FullUri # Retorna URL completa com SAS
# Gerar User Delegation SAS
$ctx_aad = New-AzStorageContext `
-StorageAccountName "stgprod001" `
-UseConnectedAccount # Usa credenciais Azure AD atuais
$udSAS = New-AzStorageBlobSASToken `
-Context $ctx_aad `
-Container "container1" `
-Blob "relatorio.pdf" `
-Permission "r" `
-ExpiryTime (Get-Date).AddDays(1) `
-Protocol HttpsOnly
# Criar Stored Access Policy
New-AzStorageContainerStoredAccessPolicy `
-Context $ctx `
-Container "container1" `
-Policy "policy-read-only" `
-Permission "r" `
-ExpiryTime (Get-Date).AddMonths(6)
# Gerar SAS com referência à SAP
$sapSAS = New-AzStorageContainerSASToken `
-Context $ctx `
-Name "container1" `
-Policy "policy-read-only"
# Listar SAPs de um container
Get-AzStorageContainerStoredAccessPolicy `
-Context $ctx `
-Container "container1"
# Revogar SAP
Remove-AzStorageContainerStoredAccessPolicy `
-Context $ctx `
-Container "container1" `
-Policy "policy-read-only"
Geração programática com SDK (Python)
from datetime import datetime, timedelta, timezone
from azure.storage.blob import (
BlobServiceClient,
BlobSasPermissions,
ContainerSasPermissions,
generate_blob_sas,
generate_container_sas,
UserDelegationKey
)
from azure.identity import DefaultAzureCredential
# Account SAS / Service SAS com Account Key
account_name = "stgprod001"
account_key = "<account-key>"
# SAS para blob específico (read, 8 horas)
sas_token = generate_blob_sas(
account_name=account_name,
container_name="container1",
blob_name="relatorio.pdf",
account_key=account_key,
permission=BlobSasPermissions(read=True),
expiry=datetime.now(timezone.utc) + timedelta(hours=8),
start=datetime.now(timezone.utc) - timedelta(minutes=5),
protocol="https",
ip="200.200.200.0/24"
)
blob_url = f"https://{account_name}.blob.core.windows.net/container1/relatorio.pdf?{sas_token}"
print(blob_url)
# User Delegation SAS com Azure AD
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url=f"https://{account_name}.blob.core.windows.net",
credential=credential
)
# Obter User Delegation Key (válida por até 7 dias)
delegation_key_start = datetime.now(timezone.utc)
delegation_key_expiry = datetime.now(timezone.utc) + timedelta(days=2)
user_delegation_key = blob_service_client.get_user_delegation_key(
key_start_time=delegation_key_start,
key_expiry_time=delegation_key_expiry
)
# Gerar User Delegation SAS
ud_sas = generate_blob_sas(
account_name=account_name,
container_name="container1",
blob_name="relatorio.pdf",
user_delegation_key=user_delegation_key, # Não usa account_key
permission=BlobSasPermissions(read=True),
expiry=datetime.now(timezone.utc) + timedelta(hours=4),
protocol="https"
)
7. Controle e Segurança
Mecanismos de revogação por tipo de SAS
Esta é a tabela mais importante para decisões de segurança:
| Tipo de SAS | Como revogar | Impacto da revogação |
|---|---|---|
| Account SAS sem SAP | Rotacionar Account Key usada para assinar | Revoga TODOS os SAS assinados com aquela key (key1 ou key2) |
| Service SAS com SAP | Deletar ou modificar a SAP | Revoga apenas os SAS que referenciam aquela SAP |
| Service SAS sem SAP | Rotacionar Account Key usada | Revoga TODOS os SAS assinados com aquela key |
| User Delegation SAS | Revogar User Delegation Key via API | Revoga todos os SAS gerados com aquela delegation key |
A storage account tem duas Account Keys (key1 e key2) exatamente para permitir rotação sem downtime: você pode rotacionar key1, atualizar aplicações para usar key2, e depois rotacionar key2. Mas durante a janela de rotação, SAS assinados com a chave rotacionada são revogados.
Princípio do menor privilégio em SAS
Configure apenas as permissões estritamente necessárias:
Proteção contra vazamento de SAS Tokens
SAS Tokens são como senhas: uma vez obtidos, qualquer pessoa pode usá-los até expirar. Estratégias de proteção:
Restrição de IP (sip): limita o uso do token ao IP ou range de origem esperado. Se o token vazar, só funciona do IP autorizado.
Protocolo HTTPS (spr=https): evita que o token seja interceptado em conexões não criptografadas.
Expiração curta: tokens de poucas horas limitam a janela de uso em caso de vazamento. Gere tokens on-demand quando necessário, não tokens de longa duração.
Não logue SAS Tokens completos: em logs de aplicação, trunque ou hash SAS Tokens. Um log com o token completo é um vetor de ataque se os logs forem comprometidos.
8. Tomada de Decisão
Quando usar cada tipo de SAS
| Situação | Tipo recomendado | Motivo |
|---|---|---|
| Compartilhar arquivo temporariamente com usuário externo | Service SAS em blob específico | Escopo mínimo, expiração curta |
| App móvel precisa fazer upload direto ao blob | Service SAS em container, permissão write | Backend gera token on-demand para cada upload |
| Parceiro externo precisa acessar container por meses | Service SAS com SAP | Pode revogar a SAP sem afetar outros acessos |
| Sistema interno (Azure Functions, AKS) precisa acessar blob | Azure AD + RBAC (não SAS) | Managed Identity é mais seguro que SAS |
| Auditoria: saber quem gerou cada SAS | User Delegation SAS | Rastreável por identidade Azure AD |
| Acesso de leitura a arquivos públicos | Anonymous Access (não SAS) | SAS é desnecessário se dados são públicos |
| Backup externo precisa ler todos os containers | Account SAS com permissão mínima + SAP | Cobre múltiplos containers com política revogável |
SAS vs. Account Keys vs. RBAC
| Método | Escopo | Expiração | Revogação | Auditoria | Ideal para |
|---|---|---|---|---|---|
| Account Key | Total | Nunca | Rotacionar chave | Limitada | Não usar para sharing |
| SAS Token | Configurável | Obrigatória | Complexa (sem SAP) | Limitada | Acesso externo temporário |
| RBAC/Azure AD | Por role | Depende da role | Imediata | Completa via Azure AD | Serviços internos, Azure resources |
| User Delegation SAS | Blob | Máx 7 dias | Via delegation key | Rastreável por identity | Melhor SAS para Blob |
9. Boas Práticas
Prefira User Delegation SAS para Blob quando possível. É o tipo mais seguro porque não usa Account Keys e pode ser rastreado para uma identidade Azure AD. Para Blob service, nunca há motivo para usar Account SAS ou Service SAS se o gerador pode se autenticar via Azure AD.
Use Stored Access Policies para qualquer SAS de longa duração. SAS que duram mais de 24 horas devem referenciar uma SAP. Isso permite revogação sem impacto sistêmico. Para SAS de horas, a revogação automática por expiração é suficiente.
Defina sempre spr=https.
SAS sem essa restrição pode ser transmitido via HTTP e interceptado. Não há cenário legítimo de produção onde HTTP deva ser aceito.
Gere SAS on-demand, não armazene tokens pré-gerados. A prática correta é que o backend gere o SAS no momento em que o cliente precisa. SAS tokens pré-gerados e armazenados (em banco de dados, arquivos de configuração) são riscos de segurança.
Use sip (signedIP) sempre que o IP do receptor for previsível.
Para integrações B2B com parceiros que têm IPs fixos, a restrição de IP adiciona uma camada crítica de proteção.
Monitore Storage Access Logs para detectar uso indevido de SAS. Configure Diagnostic Settings para enviar logs ao Log Analytics. Queries periódicas para SAS com muitas requisições ou de IPs inesperados podem indicar vazamento.
Documente cada SAS emitido para acesso de longa duração. Crie um registro (planilha, ticket, banco de dados) com: quem recebeu, para qual recurso, com quais permissões, até quando expira. SAS tokens de longa duração sem rastreamento tornam-se shadow access difícil de auditar.
10. Erros Comuns
| Erro | Por que acontece | Como evitar |
|---|---|---|
| SAS com expiração de anos | "Evitar gerar novamente depois" | Usar SAP + Service SAS com período curto e SAP de longa duração |
SAS sem spr=https | Padrão do portal às vezes inclui http | Sempre especificar explicitamente https-only |
| Rotacionar Account Key sem atualizar todos os consumidores | Esquecer que SAS assinados com a key param | Auditar todos os SAS e conexões antes de rotacionar |
| User Delegation SAS com expiração maior que 7 dias | Não conhecer o limite | User Delegation Key tem máximo de 7 dias |
| Logar a URL completa com SAS em logs de aplicação | Logs são tratados como não-sensíveis | Mascarar ou truncar SAS Token em logs |
| SAS gerado mas container/blob não existe | Criado antes do recurso existir | Verificar que o recurso existe antes de gerar SAS |
| Confundir expiração do SAS com expiração da SAP | Os dois têm expiração independente | O mais restritivo prevalece: o SAS expira pelo menor entre os dois |
| Gerar SAS com todas as permissões "por garantia" | Mentalidade de "melhor sobrar" | Definir permissões mínimas para a operação específica |
O erro mais crítico
Armazenar SAS Tokens de Account SAS (sem SAP) em código-fonte ou variáveis de ambiente de longa duração. Se o código fonte vaza (repositório público acidentalmente, ex-funcionário), todos os dados cobertos pelo SAS ficam expostos até a Account Key ser rotacionada, o que frequentemente causa downtime em outras aplicações que usam a mesma chave.
11. Operação e Manutenção
Auditar uso de SAS Tokens
# Configurar logs de storage (blob service) para Log Analytics
az monitor diagnostic-settings create \
--name "blob-access-logs" \
--resource "/subscriptions/<sub-id>/resourceGroups/rg-storage/providers/Microsoft.Storage/storageAccounts/stgprod001/blobServices/default" \
--workspace "<log-analytics-workspace-id>" \
--logs '[
{"category": "StorageRead", "enabled": true},
{"category": "StorageWrite", "enabled": true},
{"category": "StorageDelete", "enabled": true}
]'
Queries úteis no Log Analytics:
// Acessos via SAS Token (identificados por AuthenticationType)
StorageBlobLogs
| where AuthenticationType == "SAS"
| where TimeGenerated > ago(24h)
| project TimeGenerated, CallerIpAddress, OperationName, Uri, StatusCode
| order by TimeGenerated desc
// SAS com muitas requisições (possível abuso)
StorageBlobLogs
| where AuthenticationType == "SAS"
| where TimeGenerated > ago(1h)
| summarize RequestCount = count() by CallerIpAddress, bin(TimeGenerated, 5m)
| where RequestCount > 100
| order by RequestCount desc
// Tentativas de acesso negadas com SAS
StorageBlobLogs
| where AuthenticationType == "SAS" and StatusCode == 403
| project TimeGenerated, CallerIpAddress, OperationName, Uri, StatusCode, StatusText
Verificar Stored Access Policies existentes
# Listar SAPs de um container
az storage container policy list \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--output table
# Verificar se SAP expirada ainda existe
az storage container policy list \
--account-name "stgprod001" \
--account-key "<account-key>" \
--container-name "container1" \
--query "[?expiry < '$(date -u +%Y-%m-%dT%H:%M:%SZ)'].name" \
--output tsv
12. Integração e Automação
Padrão: Backend gera SAS on-demand para upload direto
Este é o padrão mais comum para aplicações móveis ou web que precisam fazer upload de arquivos:
Este padrão elimina a necessidade do arquivo passar pelo servidor backend, reduzindo latência, custo de processamento e complexidade de escalonamento.
Automação de rotação de Account Keys com atualização de SAPs
# Script: Rotacionar Account Key e recriar SAPs
param(
[string]$accountName,
[string]$resourceGroup,
[string]$keyToRotate # "key1" ou "key2"
)
# 1. Salvar SAPs existentes antes de rotacionar
$ctx = New-AzStorageContext -StorageAccountName $accountName -StorageAccountKey (
(Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $accountName) |
Where-Object { $_.KeyName -eq $keyToRotate }
).Value
$containers = Get-AzStorageContainer -Context $ctx
$existingPolicies = @{}
foreach ($container in $containers) {
$policies = Get-AzStorageContainerStoredAccessPolicy -Context $ctx -Container $container.Name
if ($policies) {
$existingPolicies[$container.Name] = $policies
}
}
# 2. Rotacionar a chave
New-AzStorageAccountKey `
-ResourceGroupName $resourceGroup `
-Name $accountName `
-KeyName $keyToRotate
Write-Output "Account Key $keyToRotate rotacionada. Todos os SAS assinados com ela foram revogados."
# 3. Criar novo contexto com nova chave
$newKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroup -Name $accountName |
Where-Object { $_.KeyName -eq $keyToRotate }).Value
$newCtx = New-AzStorageContext -StorageAccountName $accountName -StorageAccountKey $newKey
# 4. Recriar SAPs com a nova chave
foreach ($containerName in $existingPolicies.Keys) {
foreach ($policy in $existingPolicies[$containerName]) {
New-AzStorageContainerStoredAccessPolicy `
-Context $newCtx `
-Container $containerName `
-Policy $policy.Policy `
-Permission $policy.Permissions `
-ExpiryTime $policy.SharedAccessExpiryTime `
-StartTime $policy.SharedAccessStartTime
Write-Output "SAP '$($policy.Policy)' recriada no container '$containerName'"
}
}
13. Resumo Final
Pontos essenciais:
- SAS Token é uma URL assinada criptograficamente que delega acesso controlado ao Azure Storage sem expor credenciais principais
- Existem três tipos: Account SAS (múltiplos serviços, assina com Account Key), Service SAS (um serviço, assina com Account Key, suporta SAP) e User Delegation SAS (apenas Blob, assina com credencial Azure AD, mais seguro)
- O SAS Token codifica permissões, serviços, expiração, IP e protocolo nos query parameters; a assinatura (
sig) garante integridade e qualquer modificação invalida o token - Stored Access Policy (SAP) permite revogação de Service SAS sem rotacionar Account Keys
- User Delegation SAS tem validade máxima de 7 dias (limitado pela User Delegation Key)
- SAS Tokens são irrevogáveis após emissão, exceto: rotacionar Account Key (Account/Service SAS), deletar SAP (Service SAS com SAP), revogar User Delegation Key (User Delegation SAS)
Diferenças críticas:
- Account SAS vs. Service SAS: Account SAS cobre múltiplos serviços; Service SAS cobre um serviço e suporta SAP para revogação granular
- Service SAS com SAP vs. sem SAP: com SAP permite revogação imediata deletando a SAP; sem SAP só pode ser revogado rotacionando a Account Key
- User Delegation SAS vs. Account/Service SAS: User Delegation usa Azure AD (mais seguro, rastreável, revogável via delegation key); Account e Service usam Account Key (risco sistêmico em caso de comprometimento)
- SAS Token vs. RBAC: SAS é para acesso externo temporário sem identidade Azure AD; RBAC é para serviços Azure e usuários com identidade gerenciada
O que precisa ser lembrado para o AZ-104:
- User Delegation SAS requer que o usuário gerador tenha a permissão
Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey - SAP pode ser criada em: containers, blobs individuais, filas e file shares (não em nível de account)
- Um SAS sem
spr=httpsaceita HTTP; sempre especificarhttps-only - A storage account tem duas Account Keys (key1 e key2) para rotação sem downtime
- SAS Tokens são gerados no cliente; o Azure Storage apenas valida a assinatura quando o token é usado
signedStart(st) é opcional; sem ele o SAS é válido imediatamente após geração