Modern file upload application with secure, keyless Azure Blob Storage integration.
This sample shows how to use Shared Access Signature (SAS) tokens for secure, direct browser-to-storage file uploads. SAS tokens provide time-boxed and permission-boxed access to Azure Storage—allowing users to upload files for a limited time with specific permissions, without exposing storage account keys. The application uses User Delegation SAS tokens, which are backed by Microsoft Entra ID credentials instead of storage keys, providing the highest level of security and auditability.
Click the Code button above → Codespaces → Create codespace on main
az login
azd config set auth.useAzCliAuth trueSet up AZD to use Azure CLI auth.
azd upThe deployment can take up to 10 minutes.
That's it! The command creates all Azure resources, configures security, and deploys your application to Azure.
Your app will be live at: The URL will be displayed after deployment completes.
🔒 Security: Managed Identity + RBAC (no storage keys!)
- ✅ Keyless Authentication - Managed identity with RBAC
- ✅ User Delegation SAS Tokens - Microsoft Entra ID-based security
- ✅ One-Command Deploy -
azd uphandles everything - ✅ Modern Stack - React 18 + Fastify 5 + TypeScript
- ✅ Container-Native - Azure Container Apps
Start here: docs/README.md - Complete learning guide
- docs/QUICKSTART.md - Quick command reference
- docs/DEPLOYMENT.md - Complete deployment guide
- docs/LOCAL-DEVELOPMENT.md - Local development guide
- docs/FUNCTIONAL-SPEC.md - Technical specification
- docs/SAS-TOKEN-ARCHITECTURE.md - Security architecture
- docs/DIAGRAMS.md - Visual architecture diagrams
- docs/auth.md - Authentication troubleshooting
Want to develop locally? See docs/LOCAL-DEVELOPMENT.md for complete instructions.
Quick start:
# Install dependencies
npm install
# Start both API and frontend
npm run dev
# API: http://localhost:3000
# Frontend: http://localhost:5173├── azure.yaml # Azure Developer CLI configuration
├── infra/ # Bicep infrastructure templates
├── docs/ # Complete documentation
└── azure-upload-file-storage/
├── api/ # Fastify API backend
│ ├── src/
│ │ ├── lib/ # Azure Storage integration
│ │ └── routes/ # API endpoints
│ └── tests/ # API tests
└── app/ # React frontend
├── src/
│ ├── components/ # React components
│ └── lib/ # Utilities
└── public/ # Static assets
- No storage keys - Uses managed identity + RBAC
- User delegation SAS - Microsoft Entra ID-based tokens
- Expiration policy compliant - Includes
startsOnandexpiresOn - CORS configured - Proper origin validation
- HTTPS enforced - In production
- Non-root containers - Security best practices
| Command | Description |
|---|---|
azd up |
Deploy everything to Azure |
npm run dev |
Run locally (API + frontend) |
npm run build |
Build both services |
npm run docker:up |
Run with Docker Compose |
See docs/QUICKSTART.md for all available commands.
Backend: Fastify 5, @azure/identity, @azure/storage-blob, TypeScript
Frontend: React 18, Vite, Material-UI, TypeScript
Infrastructure: Azure Container Apps, Blob Storage, Managed Identity
Perfect for applications that need:
- Secure file uploads without managing storage keys
- Direct browser-to-storage uploads (no server proxy)
- Microsoft Entra ID-based security
- Scalable, serverless architecture
- Modern TypeScript development
Deployment fails?
- Ensure you're logged in:
azd auth login - Check Azure subscription:
az account show
Can't upload files?
- Wait 5-10 minutes after first deployment (RBAC propagation)
- See docs/auth.md for detailed troubleshooting
Local development issues?
- See docs/LOCAL-DEVELOPMENT.md troubleshooting section
MIT
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make changes
- Run tests:
npm run check && npm run lint && npm run build - Submit a pull request
Ready to get started? Open this repo in Codespaces, run azd auth login, then azd up. You'll have a working file upload app in minutes! 🎉

