Securing storage
The @secureStorage decorator protects your storage buckets so only authorized users can access your files.
Squid's storage feature lets you manage files with the Squid Client SDK so you can interface with your files from any client. To learn more about using Squid storage with the Squid Client SDK, view the Squid storage documentation.
The security function returns a boolean: true permits the request and false denies it.
To secure a Squid storage bucket integration, use the @secureStorage decorator within a SquidService class in the Squid backend, passing the action type and the integration ID. The following code allows full access to the built-in storage bucket:
- TypeScript
- Python
import { secureStorage, SquidService } from '@squidcloud/backend';
@secureStorage('all', 'built_in_storage')
allowAllAccessToBuiltInStorage(): boolean {
return true;
}
from squidcloud_backend import SquidService, secure_storage
class ExampleService(SquidService):
@secure_storage('all', 'built_in_storage')
def allow_all_access_to_built_in_storage(self, context: dict) -> bool:
return True
To secure a Squid storage bucket for a different storage integration, provide your integration ID in the decorator:
- TypeScript
- Python
import { secureStorage, SquidService } from '@squidcloud/backend';
@secureStorage('all', 'YOUR_STORAGE_INTEGRATION_ID')
allowAllAccessToStorageIntegration(): boolean {
return true;
}
from squidcloud_backend import SquidService, secure_storage
class ExampleService(SquidService):
@secure_storage('all', 'YOUR_STORAGE_INTEGRATION_ID')
def allow_all_access_to_storage_integration(self, context: dict) -> bool:
return True
The available action types are as follows:
'read'
The 'read' action includes reading metadata, generate download URLs, download files, and list directory contents.
'write'
The 'write' action includes inserting new files, updating existing files, and deleting files.
'insert'
The 'insert' action allows for inserting new files, but does not allow for updating the contents of existing files or deleting files.
'delete'
The 'delete' action allows for deleting existing files.
'all'
The 'all' action includes all available bucket actions.
Securing writes
The following function allows an authenticated user to upload, update, and delete files in the built-in storage bucket:
- TypeScript
- Python
import { secureStorage, SquidService } from '@squidcloud/backend';
@secureStorage('write', 'built_in_storage')
allowAuthenticatedWrites(): boolean {
return this.isAuthenticated();
}
from squidcloud_backend import SquidService, secure_storage
class ExampleService(SquidService):
@secure_storage('write', 'built_in_storage')
def allow_authenticated_writes(self, context: dict) -> bool:
return self.is_authenticated()
Securing reads
To secure reading directory names, file metadata, and generating download URLs, use the 'read' action type. The following function allows a user to generate a download URL if the file path is their user ID:
- TypeScript
- Python
import { secureStorage, SquidService, StorageContext } from '@squidcloud/backend';
@secureStorage('read', 'built_in_storage')
allowReadUserFiles(context: StorageContext): boolean {
// Validate if the requested action is to get a download URL
if (context.functionality !== 'getDownloadUrl') {
return false;
}
const userId = this.getUserAuth()?.userId;
if (!userId) return false;
// Check any paths the user is trying to read to verify they're in the user's directory
for (const path of context.pathsInBucket) {
if (!path.startsWith(`user/${userId}`)) {
return false;
}
}
return true;
}
from squidcloud_backend import SquidService, secure_storage
class ExampleService(SquidService):
@secure_storage('read', 'built_in_storage')
def allow_read_user_files(self, context: dict) -> bool:
# Validate if the requested action is to get a download URL
if context['functionality'] != 'getDownloadUrl':
return False
user_auth = self.get_user_auth()
if not user_auth:
return False
user_id = user_auth['userId']
# Check any paths the user is trying to read to verify they're in the user's directory
for path in context['pathsInBucket']:
if not path.startswith(f'user/{user_id}'):
return False
return True
Including the StorageContext object as a parameter of the function gives the security function access to information about the action the client wants to take. In Python, the same information arrives as a dict. The following shows an example StorageContext object:
{
integrationId: 'built_in_storage',
pathsInBucket: [ 'test/path/img.jpg' ],
action: 'read',
functionality: 'getFileMetadata'
}