Security Design Principles
Minimise the potential impact
If we don’t have it to lose we can’t lose it.
Do not collect or hold any personal or private data on people using the system that is not fully required to carry out the functions of the platform.
Voluntarily outsources all Authentication and Identity functions to a third party SaaS (Auth0). This means we hold zero username/passwords. Our assumption is that the service provider is much larger and has much more experience and resources applied to protecting this type of user information.
Similarly, we hold no payments information.
Least Privilege Design Principle
The Least Privilege design principle requires a minimalistic approach to granting user access rights to specific information and tools. Additionally, access rights should be time-based as to limit resources access bound to the time needed to complete necessary tasks. The implications of granting access beyond this scope will allow for unnecessary access and the potential for data to be updated out of the approved context. The assigning of access rights will limit system damaging attacks from users whether they are intentional or not.
This principle attempts to limit data changes and prevents potential damage from occurring by accident or error by reducing the number of potential interactions with a resource.
For example: Voluntarily is deployed into AWS Fargate docker containers. These containers only expose the HTTP port and have no SSH terminal access - even for system admins. We do not ‘maintain’ run time servers at all. if there is a problem our only choice is to start a new deployment task and stop the old one.
Fail-Safe Defaults Design Principle
The Fail-Safe Defaults design principle pertains to allowing access to resources based on granted access over access exclusion. This principle is a methodology for allowing resources to be accessed only if explicit access is granted to a user. By default, users do not have access to any resources until access has been granted. This approach prevents unauthorized users from gaining access to the resource until access is given.
Economy of Mechanism Design Principle
The Economy of mechanism design principle requires that systems should be designed as simple and small as possible. Design and implementation errors result in unauthorized access to resources that would not be noticed during normal use.
For example: Voluntarily uses mongoose-crudify to generate most API endpoints. This standardises the API design and ensures calls can all run through a common set of security middleware components.
Complete Mediation Design Principle
The Complete Mediation design principle states that every access to every resource must be validated for authorization.
Verify all pages and resources by default require authentication except those specifically intended to be public.
In Voluntarily all UI pages must be exported from their modules wrapped in one of the following higher order components
publicPage - page is visible to non signed in people
securePage - page requires authenticated person, redirects to sign in when visited by anon.
adminPage - page requires authenticated person with admin role.
Pages with none of the above wrappers will appear without headers or footers.
All API entry points must either be documented as public access or must route the call through the CASL Ability library to verify that the user is
isAuthenticated
has appropriate access role for the HTTP request.
receives only the data fields allowed for that role.
Open Design Design Principle
The Open Design Design Principle is a concept that the security of a system and its algorithms should not be dependent on secrecy of its design or implementation
As an open-source project all our code is open to inspection along with systems documentation and operational documents. This prevents us from implementing security through obscurity. We have to ensure that systems are robust and resilient against threats from actors having a detailed knowledge of the platform.
Separation Privilege Design Principle
The separation privilege design principle requires that all resource approved resource access attempts be granted based on more than a single condition. For example, a user should be validated for active status and has access to the specific resource.
In Voluntarily we separate authentication and authorisation. To be authenticated you must sign in with a valid username/password, social sign-in, or enterprise sign in. This status is carried in a signed JSON Web Token (JWT) passed in the cookies for the page session. However to receive a valid response from API data calls you must also have a database person ‘role’ set that maps onto the access permissions for the requested data entity e.g. OP, AP, Admin. This ensures for example that people can only edit their own personal profiles.
Roles allocation is, in turn, dependent on organisation/group membership e.g you receive OP role by belonging to an OP organisation and this gives you the privilege of creating a new Opportunity.
Note: It is possible for someone manipulating the client side code in the browser to spoof the local UI into thinking someone has specific role privileges and this will enable buttons and form elements for that role. However, these elements will fail when data calls are made to the service API as the server does not trust the client.
Least Common Mechanism Design Principle
The Least Common Mechanism design principle declares that mechanisms used to access resources should not be shared.
An example of this would be to remove API entry points that are only used for Admin or in-house reporting functions from the main voluntarily application and to deploy a second application for administration. This app can use whitelisted IP restrictions to limit access to in-house admins.
Currently Voluntarily is a single service application and has few admin-only functions.
Psychological Acceptability Design Principle
The Psychological Acceptability design principle refers to security mechanisms not make resources more difficult to access than if the security mechanisms were not present
i.e don’t make the security elements so difficult that developers, operations staff or users find ways to bypass them.
Defense in Depth Design Principle
The Defense in Depth design principle is a concept of layering resource access authorization verification in a system reduces the chance of a successful attack. This layered approach to resource authorization requires unauthorized users to circumvent each authorization attempt to gain access to a resource.
Voluntarily has three main access layers:
The client application - this is essentially untrusted. role controls here are aimed at preventing genuine users from doing the wrong thing and getting errors.
The service API - this is the ‘outer wall’ All API calls should validate user authentication and access roles. Data written through the API is sanitised and validated before storage. Data read is limited by role.
The database API - this is the ‘keep’ Data writes are schema validated, access is limited to the service platform IP address range.