Infrastructure

Databases

Any application that requires a database, should make sure that the database is not publicly accessible. This can be done in one of the following ways:

  • Private networks: by making databases only accessible within private networks, they are not accessible from the internet by design. For more information, consider the next section on networking.
  • IP-whitelisting: restricting the list of IPs that have access will result in the database only being accessible from specific locations. It is prohibited to add any personal IP addresses to the list of whitelisted IPs.

All traffic to a database, coming from an external endpoint should be encrypted via TLS. The minimum TLS version which should be used to encrypt the connection should be version 1.2.

Passwords

Database passwords should be cryptographically randomly created and be at least 20 characters long. For more information about database passwords, consider the section on passwords.

Azure

When an Azure database is used (PostgreSQL, MySQL, etc.) the setting 'Allow access to other Azure services' should be set to false. Note that this means that the IP-address 0.0.0.0 cannot be in list of whitelisted IP-addresses. Also, 'Deny public access' should be set to true.

Storage

All data that is stored should be encrypted at rest. Cloud providers (like Azure) might take care of this by default. When communicating with storage over the internet, all communications should be encrypted via TLS. The minimum TLS version which should be used to encrypt the connection should be version 1.2.

In the case that files are stored at an external storage provider like Azure Storage, and the files are either uploaded by uses, or generated by the application, it is required that the files have semi-random names.

Azure

When using Azure Storage in combination with a virtual network (VNet), it is possible to use private endpoints for secure storage endpoints. This is required when a storage account does not have to be publicly accessible.

Networking

All connections to external backend services (like a database) should be made via a private network if such a network is available and can be used for communication to these services.

For applications that make use of Kubernetes, these networks are present by default, which allow communication between Kubernetes pods and services.

Azure

Projects that are hosted within the Azure environment and make use of virtual network (VNet) should have a default set of subnets. The default set of subnets are: frontend, backend and integration. The frontend subnet dedicated to public facing applications, the backend subnet is designed to host private endpoints for databases and storage accounts, and the integration subnet hosts VNet integrations for App Services.

Virtual networks and subnets are protected by network security groups and a NAT firewall. By default, network security groups allow traffic origination from within a virtual network or peered virtual network. Additionally, a public facing subnet contains security rules that allow traffic to flow in on certain ports (e.g. 443). If there is a need to connect with an external system, traffic should always be routed through a NAT firewall. In a hub-spoke model, this should be the NAT firewall in the hub. A NAT firewall has a static IP, which can be used by external systems for IP adress whitelisting. Besides, a NAT firewall also has extensive monitoring capabilities to monitor traffic passing through the network boundary.

Web Applications

All web apps that are publicly accessible can only be served via a secure connection. More information can be found on the section about encryption. If available, web apps can communicate should communicate with other backend services (e.g. database, storage) over a private network like a VNet.

Key Vaults

Some applications might require the use of a key vault to store application secrets. Communication with the key vault should always be over an encrypted connection, which should already be enforced by the key vault provider. For more information about generic secrets, consult the section on secrets.

Azure

Azure supports Azure Key Vaults which allow for secure storage of keys, secrets and certificates. Access policies can be defined to determine who can access any of the three entities. It is preferred to use the role based access functionality, such that users are granted access based on their role instead of their identity, allowing for easier access management.

CI/CD

All infrastructure should be deployed via infrastructure as code, for more information consult the Development Policy. This requires CI/CD-pipelines to have access to several secrets that can be used to authenticate to several resource providers.

Secrets

All secrets that are injected into the pipeline should be marked as 'secured' (or an equivalent functionality). This will result in all secrets being removed from the output logs. Services like Bitrise or GitHub offer such functionality.

Service Principals

Service principals can be used to deploy infrastructure to a cloud service like Azure. These principals have access to a lot of sensitive information and should be treated as such. Therefore, all access secrets or passwords should be rotated every 12 months and can only be stored in the CI/CD-environment as a secure secret.