Securing database access
The security rules for database access works to authorize client request for database operations. Authorization works on the operation level (create, read, update, delete) for each table / collection in the database. This means that you can have different rules for different operations. Here's a sample snippet which shows the rules on the
users collection in MongoDB. Operations
read are allowed while
delete are blocked.
modules: crud: mongo: enabled: true conn: mongodb://localhost:27017 isPrimary: true collections: users: isRealtimeEnabled: false rules: # These are the rules applied on this collection create: rule: allow read: rule: allow update: rule: deny delete: rule: deny # Config for other modules go here
You can add multiple databases under the
crud section. Inside a database, you can add multiple collections under it's
collections section. Each
rules section which can define rules for various operations like
delete. An operation is denied if there is no corresponding rule for it in the config file. This ensures that all the operations are secure by default.
With security rules for database you can:
- Allow / deny access to a collection.
- Allow a particular operation on a collection only if the user is authenticated.
- Allow a particular operation on a collection only if certain conditions are met (via JSON rules or custom logic).
Popular use cases
- Role based authentication (For example only allow admin to delete a project)
- Allow a user to be able to query only his / her own data.
- Allow users to read posts without signin but allow only signed in users to create a post.
- Check if the request contains a certain field.
- The Instagram problem - Allow a user to view a profile only if it is public or if he is following them.
- Custom validation.
All these problems can be solved by the security module of Space Cloud.
All CRUD requests contains certain variables which are availabe to you for matching any condition. These variables are generated by the functions of client libraries of Space Cloud you use on frontend. The following variables are available to the security rules for appying any conditions you like:
- auth: The claims present in the JWT token. If you are using in-built user management service of Space Cloud, then the
roleof the user. While making a custom service, you are free to choose the claims which go inside the JWT token and thus available in the
- find: Present when a where clause is supplied by the
wheremethod in client libraries (Follows the MongoDB query syntax).
- update: Present for update operations. It contains all the update operations like
push, etc. (Follows MongoDB DSL).
- doc: Present for insert operation. (The document(s) to be inserted)
- op: "one | all" Present for all operations.
Allow anonymous access
You can disable authentication and authorization for a particular operation on a table completely by using
allow. The request is allowed to be made even if the JWT token is absent in the request. You might want to use this when you want your users to perform certain operation without signin (For example, read products table of an e-commerce app). Here's how to give access to a particular operation using
rules: read: rule: allow
This rule is to deny all incoming requests irrespective of any thing. It is especially useful to deny certain dangerous operations like
delete while selectively allowing the other ones. (For example, deny access to delete products table). Here's how to deny access to a particular operation using
rules: delete: rule: deny
Allow only authenticated users
You can allow a certain operation on a table only if the user is authenticated. (For example, allow only logged in users to bookmark a product). This rule is used to allow the request only if a valid JWT token is found in the request. No checks are imposed beyond that. Basically it authorizes every request which has passed the authentication stage. Here's how to allow a operation for authenticated users:
rules: create: rule: authenticated
Allow operation on certain conditions
Many a times you might want a user to perform a particular operation only when certain conditions are met. For example, a user can edit a post only if it is uploaded by him. Another use case might be allowing a user to read a profile only if it is public or the user is following him (Instagram problem). Such conditions might require you to check the value of certain fields from the incoming request or from the database. Or it can be a custom validation altogether. The security rules in Space Cloud are made keeping this flexibility in mind.
Match incoming requests
This rule is used to allow a certain request only when a certain condition has been met and all the variables required for matching are present in the request itself. Each CRUD request contains certain variable (
op) present in the
args object. Generally this rule is used to match the input parameters (like the where clause or certain fields in the document to be inserted) with the auth object. It can also be used for role based authentication.
The basic syntax looks like this:
rule: match eval: == | != | > | >= | < | <= # Any one of them type: string | number | bool # Any one of them f1: field1 # A value or variable f2: field2 # A value or variable
Example (make sure user can query only his
rules: query: rule: match eval: == type: string f1: args.auth.id # Assuming id is the JWT claim containing the userId f2: args.find.userId # Assuming the `todos` table contains the field `userId`
Example (Role based authentication - allow only admin to delete a project):
rules: query: rule: match eval: == type: string f1: args.auth.role # Assuming role is the JWT claim containing the role of user f2: admin
Example (Check if a field is present in the request):
rules: query: rule: match eval: == type: bool f1: utils.exists(args.find.postId) f2: true
utils.exists is a utility function by the security rules which checks if a given field exists or not and returns true or false.
This rule is used to allow a certain request only if a database request returns successfully. The query's find clause is generated dynamically using this rule. The query is considered to be successful if even a single row is successfully returned.
The basic syntax looks like this:
rule: query db: mongo | sql-mysql | sql-postgres # Any one of them col: collection # Name of the table / collection find: mongo-find query # Find object following MongoDB query syntax
query rule executes a database query with the user defined find object with operation type set to
one. It is useful for policies which depend on the values stored in the database.
Example (make sure user can query only public
rules: query: rule: query db: mongo col: profiles find: userId: args.find.userId # Assuming profiles has field `userId` isPublic: true # Assuming profiles has field `isPublic`
Combine multiple conditions
You can mix and match several
query rules together to tackle complex authorization tasks (like the Instagram problem) using the
The basic syntax looks like this:
rule: and | or clauses: array_of_rules
Example (The Instagram problem - Make sure the user can query a profile only if it's public or he is a follower)
rule: or clauses: - rule: query db: mongo col: profiles find: userId: args.find.userId # Assuming profiles has field `userId` isPublic: true - rule: query db: mongo col: profiles find: followers: $in: args.auth.userId # Assuming followers is an array of user ids
In case where the matching and db query for validating conditions are not enough, you can bring your own custom validation logic by writing a function with the functions module. You can configure Space Cloud to use your function to authorize a particular request. Here's an example showing how to do this by rule
## Asuming you have written a service `my-service` with a function `my-service` using functions mesh rule: func service: my-service func: my-func
In the above case,
my-func will receive the
auth object and the
params object (consisting of data variables -
op) as arguments of the function. See functions mesh to understand how to write a function. The request will be considered authorized by the Space Cloud in this case only when the function returns an object with
ack property set to true.
Great! You have learned how to secure database access. You may now checkout the security rules for file storage module.