Securing distributed locks
Distributed locks manage access to shared resources to transact data in order. The @secureDistributedLock decorator secures locks.
Distributed locks resolve race conditions by locking access to shared resources to a single client at a time. By default, clients are denied access to distributed locks. Use the @secureDistributedLock() decorator in the SquidService class in the Squid backend to authorize client access to the lock. The security function returns a boolean: true permits the request and false denies it.
To allow all clients access to lock any distributed lock, use a security function with the following format:
- TypeScript
- Python
import { secureDistributedLock, SquidService } from '@squidcloud/backend';
@secureDistributedLock()
allowAllAccessToAcquiringLock(): boolean {
return true;
}
from squidcloud_backend import SquidService, secure_distributed_lock
class ExampleService(SquidService):
@secure_distributed_lock()
def allow_all_access_to_acquiring_lock(self, context: dict) -> bool:
return True
When a client tries to use a distributed lock, the mutex value they are using is passed to the Squid backend in the DistributedLockContext (a dict with a mutex key in Python). The following security function shows how you could secure the lock based on mutex value where the allUsers mutex is available to all authenticated users, and the admin mutex is available only to users with the admin attribute in their auth token:
- TypeScript
- Python
import { secureDistributedLock, SquidService, DistributedLockContext } from '@squidcloud/backend';
@secureDistributedLock()
allowAllAccessToAcquiringLock(context: DistributedLockContext): boolean {
// If the mutex is "allUsers", return true if authenticated
if (context.mutex === "allUsers") {
return this.isAuthenticated();
}
// If the mutex is "admin", return true if the user is an admin
if (context.mutex === "admin") {
const userAuth = this.getUserAuth();
return !!userAuth?.attributes['admin'];
}
return false; // all others are not allowed
}
from squidcloud_backend import SquidService, secure_distributed_lock
class ExampleService(SquidService):
@secure_distributed_lock()
def allow_all_access_to_acquiring_lock(self, context: dict) -> bool:
# If the mutex is "allUsers", return True if authenticated
if context['mutex'] == 'allUsers':
return self.is_authenticated()
# If the mutex is "admin", return True if the user is an admin
if context['mutex'] == 'admin':
user_auth = self.get_user_auth()
return bool(user_auth and user_auth.get('attributes', {}).get('admin'))
return False # all others are not allowed
To view an example of an app that uses a distributed lock, check out this blog post.