fai-azure-storage-patterns — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited fai-azure-storage-patterns (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Design patterns for blobs, queues, tables, and files with security and lifecycle management.
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: storageName
location: location
kind: 'StorageV2'
sku: { name: 'Standard_ZRS' }
identity: { type: 'SystemAssigned' }
properties: {
allowBlobPublicAccess: false
allowSharedKeyAccess: false // Force AAD/MI auth
minimumTlsVersion: 'TLS1_2'
publicNetworkAccess: 'Disabled'
networkAcls: { defaultAction: 'Deny' }
supportsHttpsTrafficOnly: true
}
}from azure.storage.blob import BlobServiceClient
from azure.identity import DefaultAzureCredential
client = BlobServiceClient(
account_url="https://storageai.blob.core.windows.net",
credential=DefaultAzureCredential(),
)
container = client.get_container_client("documents")
with open("report.pdf", "rb") as f:
container.upload_blob("reports/2026/report.pdf", f, overwrite=True,
metadata={"category": "invoice", "processed": "false"})from azure.storage.queue import QueueServiceClient
import json, base64
queue_client = QueueServiceClient(
account_url="https://storageai.queue.core.windows.net",
credential=DefaultAzureCredential(),
).get_queue_client("processing-tasks")
# Enqueue
message = json.dumps({"blob": "reports/2026/report.pdf", "action": "embed"})
queue_client.send_message(base64.b64encode(message.encode()).decode())
# Dequeue and process
for msg in queue_client.receive_messages(max_messages=5, visibility_timeout=60):
task = json.loads(base64.b64decode(msg.content))
process(task)
queue_client.delete_message(msg)from azure.storage.blob import generate_blob_sas, BlobSasPermissions
from datetime import datetime, timedelta, timezone
sas = generate_blob_sas(
account_name="storageai",
container_name="documents",
blob_name="reports/2026/report.pdf",
account_key=None, # Use user delegation key with MI instead
permission=BlobSasPermissions(read=True),
expiry=datetime.now(timezone.utc) + timedelta(hours=1),
)
url = f"https://storageai.blob.core.windows.net/documents/reports/2026/report.pdf?{sas}"{
"rules": [
{ "name": "cool-30d", "type": "Lifecycle", "definition": {
"filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["documents/"] },
"actions": { "baseBlob": { "tierToCool": { "daysAfterModificationGreaterThan": 30 }}}
}},
{ "name": "archive-90d", "type": "Lifecycle", "definition": {
"filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["documents/"] },
"actions": { "baseBlob": { "tierToArchive": { "daysAfterModificationGreaterThan": 90 }}}
}}
]
}| Issue | Cause | Fix |
|---|---|---|
| Unexpected cost growth | No lifecycle tiering | Add Cool/Archive transitions |
| 403 on blob access | Shared key disabled, MI role missing | Grant Storage Blob Data Contributor |
| SAS token abuse | Long expiry or broad permissions | Use user delegation SAS with 1-hour max |
| Queue poison messages | No max dequeue count | Set dequeueCount limit, move to poison queue |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.