permas-sas-token-sdk
v1.0.1
Published
Permas SDK for secure, controlled access to Azure Storage resources using SAS tokens. Simplifies cloud storage security across platforms and environments.
Maintainers
Readme
PERMAS SAS Token SDK
A comprehensive SDK for secure, controlled access to cloud storage resources using Azure Storage SAS (Shared Access Signature) tokens. Developed by Perceptive Focus to simplify security management across diverse technology stacks.
Key Features
- Cross-Platform: Works seamlessly in browsers, Node.js applications, and modern frameworks
- Multi-Resource Support: Generate tokens for Blob, Table, Queue, File, and Account-level resources
- Fine-Grained Access Control: Set precise permissions and expiration times
- Secure By Design: Isolates security concerns from application code
- Beyond Azure: Integrate with non-Azure applications that need to access Azure storage
Integration Possibilities
While this SDK uses Azure Storage on the backend, it can be integrated with:
- Multi-Cloud Applications: Access Azure storage from applications hosted on AWS, GCP, or other clouds
- On-Premises Systems: Connect legacy systems to cloud storage without extensive refactoring
- Third-Party Services: Enable external services to access your storage with limited, controlled permissions
- Hybrid Architectures: Bridge on-premises and cloud systems with secure storage access
Installation
npm (Node.js, React, etc.)
npm install permas-sas-token-sdkBrowser via CDN
<!-- Production version (minified) -->
<script src="https://unpkg.com/permas-sas-token-sdk/dist/sas-token-sdk.min.js"></script>
<!-- Development version -->
<script src="https://unpkg.com/permas-sas-token-sdk/dist/sas-token-sdk.js"></script>Quick Start
Browser
<script src="https://unpkg.com/permas-sas-token-sdk/dist/sas-token-sdk.min.js"></script>
<script>
// Initialize the client
const sasClient = new SasTokenClient({
apiUrl: 'https://your-function-url.azurewebsites.net/api/sas',
apiKey: 'your-function-key',
defaultExpiryHours: 24,
debug: false
});
// Generate a blob SAS token
async function generateSas() {
try {
const result = await sasClient.generateBlobSas({
containerName: 'documents',
permissions: 'r', // Read-only
blobPath: 'folder/file.pdf' // Optional, for specific blob
});
if (result.success) {
console.log('SAS Token URL:', result.data.url);
window.open(result.data.url, '_blank');
} else {
console.error('Error:', result.error);
}
} catch (error) {
console.error('Failed:', error);
}
}
</script>Node.js (CommonJS)
const SasTokenClient = require('permas-sas-token-sdk');
// Initialize the client
const sasClient = new SasTokenClient({
apiUrl: 'https://your-function-url.azurewebsites.net/api/sas',
apiKey: 'your-function-key',
defaultExpiryHours: 24,
debug: false
});
// Generate a blob SAS token
async function generateSas() {
try {
const result = await sasClient.generateBlobSas({
containerName: 'documents',
permissions: 'r', // Read-only
blobPath: 'folder/file.pdf' // Optional, for specific blob
});
if (result.success) {
console.log('SAS Token URL:', result.data.url);
} else {
console.error('Error:', result.error);
}
} catch (error) {
console.error('Failed:', error);
}
}
generateSas();Modern JavaScript / TypeScript (ESM)
import { SasTokenClient } from 'permas-sas-token-sdk';
// Initialize the client
const sasClient = new SasTokenClient({
apiUrl: 'https://your-function-url.azurewebsites.net/api/sas',
apiKey: 'your-function-key',
defaultExpiryHours: 24,
debug: false
});
// Generate a blob SAS token
async function generateSas() {
try {
const result = await sasClient.generateBlobSas({
containerName: 'documents',
permissions: 'r', // Read-only
blobPath: 'folder/file.pdf' // Optional, for specific blob
});
if (result.success) {
console.log('SAS Token URL:', result.data.url);
} else {
console.error('Error:', result.error);
}
} catch (error) {
console.error('Failed:', error);
}
}React Component Example
import React, { useState } from 'react';
import { SasTokenClient } from 'permas-sas-token-sdk';
// Initialize the client
const sasClient = new SasTokenClient({
apiUrl: 'https://your-function-url.azurewebsites.net/api/sas',
apiKey: 'your-function-key'
});
function BlobViewer() {
const [url, setUrl] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const fetchDocument = async () => {
setLoading(true);
setError('');
try {
const result = await sasClient.generateBlobSas({
containerName: 'documents',
permissions: 'r',
blobPath: 'reports/annual-report.pdf'
});
if (result.success) {
setUrl(result.data.url);
} else {
setError(result.error || 'Failed to generate SAS token');
}
} catch (err) {
setError(err.message || 'An error occurred');
} finally {
setLoading(false);
}
};
return (
<div>
<button onClick={fetchDocument} disabled={loading}>
{loading ? 'Loading...' : 'View Document'}
</button>
{error && <div className="error">{error}</div>}
{url && (
<div>
<iframe src={url} width="100%" height="500px" />
</div>
)}
</div>
);
}
export default BlobViewer;Non-Azure Integration Examples
AWS Lambda to Azure Storage
// AWS Lambda function that uses PERMAS SAS Token SDK to access Azure Storage
const { SasTokenClient } = require('permas-sas-token-sdk');
exports.handler = async (event) => {
const sasClient = new SasTokenClient({
apiUrl: process.env.PERMAS_API_URL,
apiKey: process.env.PERMAS_API_KEY
});
// Process S3 event but store results in Azure Blob
const result = await sasClient.generateBlobSas({
containerName: 'processed-data',
permissions: 'rw', // Read and write
expiryHours: 1
});
if (result.success) {
// Use the SAS URL to upload processed data to Azure
// This allows your AWS function to securely interact with Azure storage
return {
statusCode: 200,
body: JSON.stringify({message: 'Data processed and stored in Azure'})
};
} else {
return {
statusCode: 500,
body: JSON.stringify({error: result.error})
};
}
};On-Premises Application Integration
// Java example using PERMAS SAS Token SDK via REST
import java.net.HttpURLConnection;
import java.net.URL;
// ... other imports
public class LegacySystemIntegration {
private final String apiUrl = "https://your-function-url.azurewebsites.net/api/sas";
private final String apiKey = "your-function-key";
public String getFileAccessUrl(String fileName) throws Exception {
// Call your PERMAS SAS Token API to get a secure access URL
URL url = new URL(apiUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("x-functions-key", apiKey);
conn.setRequestProperty("Content-Type", "application/json");
// Request body to get file-specific SAS token
String requestBody = "{\"resourceType\":\"blob\",\"resourcePath\":\"reports\","
+ "\"nestedPath\":\"" + fileName + "\",\"permissions\":\"r\"}";
// Send request and parse response to get SAS URL
// ...
return sasUrl; // Return the secure URL to access Azure storage
}
// Now legacy applications can access modern cloud storage securely
}API Reference
Initialization
const sasClient = new SasTokenClient({
apiUrl: 'https://your-function-url.azurewebsites.net/api/sas',
apiKey: 'your-function-key',
defaultExpiryHours: 24, // Optional, defaults to 24
debug: false // Optional, defaults to false
});Methods
All methods return a Promise that resolves to a SasTokenResponse object:
interface SasTokenResponse {
success: boolean;
data?: {
sasToken: string; // The SAS token string
url: string; // Full URL with SAS token
resourceLevel: string; // Resource type (container, blob, etc.)
validUntil: string; // ISO date when token expires
storageEndpoint: string; // Base storage URL
};
error?: string; // Error message if success is false
}Diagnostics
Check if the API is accessible:
const result = await sasClient.diagnose();
// result: { status: 'success|error', message: '...', diagnosticInfo: {...} }Blob Storage
// Container-level access
const result = await sasClient.generateBlobSas({
containerName: 'documents',
permissions: 'r', // r=read, w=write, d=delete, l=list, a=add, c=create
expiryHours: 48 // Optional
});
// Blob-specific access
const result = await sasClient.generateBlobSas({
containerName: 'documents',
blobPath: 'reports/annual-report.pdf',
permissions: 'r',
expiryHours: 2 // Optional
});Table Storage
const result = await sasClient.generateTableSas({
tableName: 'customers',
permissions: 'r', // r=read, a=add, u=update, d=delete
expiryHours: 24 // Optional
});Queue Storage
const result = await sasClient.generateQueueSas({
queueName: 'messages',
permissions: 'ap', // a=add, p=process, r=read, u=update
expiryHours: 12 // Optional
});File Storage
// Share-level access
const result = await sasClient.generateFileSas({
shareName: 'documents',
permissions: 'r', // r=read, c=create, w=write, d=delete, l=list
expiryHours: 24 // Optional
});
// File-specific access
const result = await sasClient.generateFileSas({
shareName: 'documents',
filePath: 'reports/quarterly-report.xlsx',
permissions: 'r',
expiryHours: 24 // Optional
});Account-level SAS
const result = await sasClient.generateAccountSas({
permissions: 'btqf-sco-rwl', // Format: services-resourceTypes-permissions
expiryHours: 1 // Optional
});Permissions Reference
Blob Storage Permissions
r- Reada- Addc- Createw- Writed- Deletel- List
Table Storage Permissions
r- Reada- Addu- Updated- Delete
Queue Storage Permissions
r- Reada- Addp- Processu- Update
File Storage Permissions
r- Readc- Createw- Writed- Deletel- List
Account SAS Format
The account SAS permissions use the format: services-resourceTypes-permissions
Services:
b- Blobt- Tableq- Queuef- File
Resource Types:
s- Servicec- Containero- Object
Permissions:
r- Readw- Writed- Deletel- Lista- Addc- Createu- Updatep- Process
Example: btqf-sco-rwl means:
- Services: Blob, Table, Queue, and File
- Resource types: Service, Container, and Object
- Permissions: Read, Write, and List
License
MIT
