Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellaneous fixes from TRESA testing #2068

Merged
merged 22 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cbaedab
:memo: Fix argument name
jemrobinson Jul 31, 2024
635ddb4
:bug: Fix subscription name regex
jemrobinson Jul 31, 2024
d469bf2
:bug: Allow special characters at beginning and end of subscription name
jemrobinson Jul 31, 2024
fb24a18
:memo: Remove unnecessary underscores in example SHM command
jemrobinson Jul 31, 2024
bde85ec
:memo: Add hatch warning to each place where DSH code is run
jemrobinson Jul 31, 2024
677ee4a
:memo: Add subscription argument to call
jemrobinson Jul 31, 2024
f6d9ef3
:sparkles: Add an explicit list of Azure locations
jemrobinson Jul 31, 2024
294f5d4
:bug: Ensure that stack name only contains '-' as a separator
jemrobinson Jul 31, 2024
3fc10cb
:memo: Better explanation of phone format
jemrobinson Jul 31, 2024
8655258
:memo: Update syntax in management docs page
jemrobinson Jul 31, 2024
0c4e5b9
:memo: Simplify add-user documentation
jemrobinson Jul 31, 2024
f3052de
:loud_sound: Fix log message
jemrobinson Jul 31, 2024
efa0a4c
:bug: Update validation of Azure subscription names which can accept …
jemrobinson Jul 31, 2024
1933826
:rotating_light: Fix indentation
jemrobinson Jul 31, 2024
c03bb15
:memo: Replace backticks with bold as appropriate
jemrobinson Aug 1, 2024
b723c98
:memo: Better explanation of SHM command line options
jemrobinson Aug 1, 2024
8be7cdd
:memo: Split long command line expressions
jemrobinson Aug 1, 2024
00bc34f
:memo: Reorder and expand docs on user management
jemrobinson Aug 1, 2024
db22ba7
:memo: Replace backticks with colons
jemrobinson Aug 1, 2024
7fdd2b3
:memo: Apply suggestions from code review
jemrobinson Aug 2, 2024
8a488c5
Merge branch 'develop' into tresa-testing
jemrobinson Aug 2, 2024
50412e6
:coffin: Drop private endpoint section as this does not seem to be ne…
jemrobinson Aug 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data_safe_haven/external/api/graph_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ def create_user(
json={"emailAddress": email_address},
)
except DataSafeHavenMicrosoftGraphError as exc:
msg = f"Failed to add authentication email address'{email_address}'."
msg = f"Failed to add authentication email address '{email_address}'."
raise DataSafeHavenMicrosoftGraphError(msg) from exc

# Set the authentication phone number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pulumi_azure_native import resources

from data_safe_haven.config import Context, SREConfig
from data_safe_haven.functions import replace_separators
from data_safe_haven.infrastructure.common import DockerHubCredentials

from .sre.application_gateway import (
Expand Down Expand Up @@ -65,7 +66,9 @@ def __init__(
self.context = context
self.config = config
self.graph_api_token = graph_api_token
self.stack_name = f"shm-{context.name}-sre-{config.name}"
self.stack_name = replace_separators(
f"shm-{context.name}-sre-{config.name}", "-"
)
self.tags = {"component": f"SRE {config.name}"} | context.tags

def __call__(self) -> None:
Expand Down
65 changes: 62 additions & 3 deletions data_safe_haven/validators/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,75 @@ def aad_guid(aad_guid: str) -> str:


def azure_location(azure_location: str) -> str:
if not re.match(r"^[a-z]+[0-9]?[a-z]*$", azure_location):
# Generate a list of locations with the following command:
# `az account list-locations --query "[?metadata.regionType == 'Physical'].name"`
locations = [
"australiacentral",
"australiacentral2",
"australiaeast",
"australiasoutheast",
"brazilsouth",
"brazilsoutheast",
"brazilus",
"canadacentral",
"canadaeast",
"centralindia",
"centralus",
"centraluseuap",
"eastasia",
"eastus",
"eastus2",
"eastus2euap",
"eastusstg",
"francecentral",
"francesouth",
"germanynorth",
"germanywestcentral",
"israelcentral",
"italynorth",
"japaneast",
"japanwest",
"jioindiacentral",
"jioindiawest",
"koreacentral",
"koreasouth",
"mexicocentral",
"northcentralus",
"northeurope",
"norwayeast",
"norwaywest",
"polandcentral",
"qatarcentral",
"southafricanorth",
"southafricawest",
"southcentralus",
"southeastasia",
"southindia",
"spaincentral",
"swedencentral",
"switzerlandnorth",
"switzerlandwest",
"uaecentral",
"uaenorth",
"uksouth",
"ukwest",
"westcentralus",
"westeurope",
"westindia",
"westus",
"westus2",
"westus3",
]
if azure_location not in locations:
msg = "Expected valid Azure location, for example 'uksouth'."
raise ValueError(msg)
return azure_location


def azure_subscription_name(subscription_name: str) -> str:
# https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/resource-name-rules
if not re.match(r"^[a-zA-Z][a-zA-Z0-9\- ]+[a-zA-Z0-9]$", subscription_name):
msg = "Azure subscription names can only contain alphanumeric characters and hyphens.\n They must start with a letter and end with an alphanumeric character."
if not re.match(r"^[a-zA-Z0-9\- \[\]]+$", subscription_name):
msg = "Azure subscription names can only contain alphanumeric characters, spaces and particular special characters."
JimMadge marked this conversation as resolved.
Show resolved Hide resolved
raise ValueError(msg)
return subscription_name

Expand Down
2 changes: 1 addition & 1 deletion docs/source/deployment/configure_entra_id.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ This is necessary both to secure logins and to allow users to set their own pass
- Sign in to the [Microsoft Entra admin centre](https://entra.microsoft.com/)
- Browse to **{menuselection}`Protection --> Authentication methods`** from the menu on the left side
- Browse to **{menuselection}`Manage --> Policies`** from the secondary menu on the left side
- For each of **Microsoft Authenticator**, **SMS**, **Third-party software OATH tokens**, **Voice call** and **Email OTP** click on the method name
- For each of **Microsoft Authenticator**, **SMS**, **Voice call** and **Email OTP** click on the method name
- Ensure the slider is set to **Enable** and the target to **All users**
- Click the **{guilabel}`Save`** button

Expand Down
62 changes: 45 additions & 17 deletions docs/source/deployment/deploy_shm.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,29 +38,57 @@ Follow the instructions [here](https://learn.microsoft.com/en-us/entra/fundament

## Deployment

::::{admonition} Ensure you are using a hatch shell
:class: dropdown important

You must use a `hatch` shell to run any `dsh` commands.
From the project base directory run:

:::{code} shell
$ hatch shell
:::

This ensures that you are using the intended version of Data Safe Haven with the correct set of dependencies.
::::

Before deploying the Safe Haven Management (SHM) infrastructure you need to decide on a few parameters:

- `entra_tenant_id`: Tenant ID for the Entra ID used to manage TRE users
- `fqdn`: Fully-qualified domain you want your users to belong to and to access your TRE from
- `location`: Azure location where you want your resources deployed
**entra_tenant_id**
: Tenant ID for the Entra ID used to manage TRE users

:::{admonition} How to find your Microsoft Entra Tenant ID
:class: dropdown note
:::{admonition} How to find your Microsoft Entra Tenant ID
:class: dropdown hint

- Go to the [Microsoft Entra admin centre](https://entra.microsoft.com/)
- Click on your username / profile icon in the top right
- Click **{guilabel}`Switch directory`** in the dropdown menu
- Ensure that you have selected the directory you chose above
- Browse to **{menuselection}`Identity --> Overview`** from the menu on the left side.
- Take note of the `Tenant ID`
- Go to the [Microsoft Entra admin centre](https://entra.microsoft.com/)
- Click on your username / profile icon in the top right
- Click **{guilabel}`Switch directory`** in the dropdown menu
- Ensure that you have selected the directory you chose above
- Browse to **{menuselection}`Identity --> Overview`** from the menu on the left side.
- Take note of the `Tenant ID`

:::
:::

**fqdn**
: Domain name that your TRE users will belong to.

:::{hint}
Use a domain that you own! If you use _e.g._ `bakerst.london` here your users will be given usernames like `sherlock.holmes@bakerst.london`
:::

**location**
: Azure location where you want your resources deployed.

:::{hint}
Use the short name without spaces, _e.g._ **uksouth** not **UK South**
:::

Once you've decided on these, run the following command: [approx 5 minutes]:

```{code} shell
$ dsh shm deploy --entra-tenant-id _YOUR_ENTRA_TENANT_ID_ --fqdn _YOUR_DOMAIN_NAME_ --location _YOUR_LOCATION_
```
:::{code} shell
$ dsh shm deploy --entra-tenant-id YOUR_ENTRA_TENANT_ID \
--fqdn YOUR_DOMAIN_NAME \
--location YOUR_LOCATION
:::

:::{note}
You will be prompted to log in to the Azure CLI and to the Graph API.
Expand All @@ -73,7 +101,7 @@ You will be prompted to log in to the Azure CLI and to the Graph API.
:::{important}
You may be asked to delegate your domain name to Azure. To do this, you'll need to know details about the parent domain. For example, if you are deploying to `dsh.example.com` then the parent name is `example.com`.

- Follow [this tutorial](https://learn.microsoft.com/en-us/azure/dns/dns-delegate-domain-azure-dns#delegate-the-domain) if the parent domain is hosted outside Azure
- Follow [this tutorial](https://learn.microsoft.com/en-us/azure/dns/tutorial-public-dns-zones-child#verify-the-child-dns-zone) if the parent domain is hosted in Azure
- Follow [this tutorial](https://learn.microsoft.com/en-us/azure/dns/dns-delegate-domain-azure-dns#delegate-the-domain) if the parent domain is hosted **outside Azure**
- Follow [this tutorial](https://learn.microsoft.com/en-us/azure/dns/tutorial-public-dns-zones-child#verify-the-child-dns-zone) if the parent domain is hosted **in Azure**

:::
56 changes: 41 additions & 15 deletions docs/source/deployment/deploy_sre.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,37 @@

# Deploy a Secure Research Environment

These instructions will deploy a new Secure Research Environment (SRE).
jemrobinson marked this conversation as resolved.
Show resolved Hide resolved

::::{admonition} Ensure you are using a hatch shell
:class: dropdown important

You must use a `hatch` shell to run any `dsh` commands.
From the project base directory run:

:::{code} shell
$ hatch shell
:::

This ensures that you are using the intended version of Data Safe Haven with the correct set of dependencies.
::::

## Configuration

Each project will have its own dedicated Secure Research Environment (SRE).
Each project will have its own dedicated SRE.

- Create a configuration file

```console
> dsh config template --file config.yaml
```
:::{code} shell
$ dsh config template --file PATH_YOU_WANT_TO_SAVE_YOUR_YAML_FILE_TO
:::

- Edit this file in your favourite text editor, replacing the placeholder text with appropriate values for your setup.

```yaml
::::{admonition} Example YAML configuration file
:class: dropdown tip

:::{code} yaml
azure:
subscription_id: # ID of the Azure subscription that the TRE will be deployed to
tenant_id: # Home tenant for the Azure account used to deploy infrastructure: `az account show`
Expand All @@ -35,31 +53,39 @@ sre:
software_packages: # any/pre-approved/none: which packages from external repositories to allow
timezone: # Timezone in pytz format (eg. Europe/London)
workspace_skus: # List of Azure VM SKUs - see cloudprice.net for list of valid SKUs
```
:::

::::

## Upload the configuration file

- Upload the config to Azure. This will validate your file and report any problems.

```{code} shell
$ dsh config upload config.yaml
```
:::{code} shell
$ dsh config upload PATH_TO_YOUR_EDITED_YAML_FILE
:::

:::{hint}
If you want to make changes to the config, edit this file and then run `dsh config upload` again
:::

## Requirements

:::{important}
As private endpoints for flexible PostgreSQL are still in preview, the following command is currently needed:

```{code} shell
$ az feature register --name "enablePrivateEndpoint" --namespace "Microsoft.DBforPostgreSQL"
```
:::{code} shell
$ az feature register --name "enablePrivateEndpoint" \
--namespace "Microsoft.DBforPostgreSQL" \
--subscription NAME_OR_ID_OF_YOUR_SUBSCRIPTION
:::
jemrobinson marked this conversation as resolved.
Show resolved Hide resolved

:::

## Deployment

- Deploy each SRE individually [approx 30 minutes]:

```{code} shell
$ dsh sre deploy _YOUR_SRE_NAME_
```
:::{code} shell
$ dsh sre deploy YOUR_SRE_NAME
:::
14 changes: 5 additions & 9 deletions docs/source/deployment/index.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Deployment

```{toctree}
:::{toctree}
:hidden:

setup_context.md
deploy_shm.md
configure_entra_id.md
deploy_sre.md
```
:::

Deploying an instance of the Data Safe Haven involves the following steps:

Expand Down Expand Up @@ -44,12 +44,8 @@ Download or checkout this code from GitHub.
Please contact the development team in case of any problems.
:::

Enter the base directory and start a new `hatch` environment by doing the following:

```{code} shell
$ hatch shell
```
Enter the base directory and install Python dependencies with `hatch` by doing the following:

:::{hint}
Using a hatch environment this way ensures that you are using the intended version of Data Safe Haven with the correct set of dependencies.
:::{code} shell
$ hatch run true
:::
15 changes: 9 additions & 6 deletions docs/source/deployment/setup_context.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ You can specify the directory where your context configuration (`context.yaml`)

- You will need to provide some options to set up your DSH context. You can see what these are by running the following:

```{code} shell
:::{code} shell
$ dsh context add --help
```
:::

- Run a command like the following to create your local context file.

```{code} shell
$ dsh context add --admin-group-name _AZURE_GROUP_CONTAINING_ALL_ADMINISTRATORS_ --name _CONTEXT_NAME_ --description _HUMAN_FRIENDLY_NAME_ --subscription _AZURE_SUBSCRIPTION_NAME_
```
:::{code} shell
$ dsh context add --admin-group-name AZURE_SECURITY_GROUP_CONTAINING_ALL_ADMINISTRATORS \
--name NAME_WITH_ONLY_LETTERS_NUMBERS_AND_UNDERSCORES \
--description HUMAN_FRIENDLY_DESCRIPTION_OF_YOUR_TRE \
--subscription-name AZURE_SUBSCRIPTION_NAME
:::

:::{note}
If you have multiple contexts defined, you can select which context you want to use with `dsh context switch _CONTEXT_NAME_`.
If you have multiple contexts defined, you can select which context you want to use with `dsh context switch CONTEXT_NAME`.
:::
8 changes: 4 additions & 4 deletions docs/source/design/security/reference_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ The set of controls applied at the Alan Turing Institute are discussed here, tog
### Turing configuration setting:

- Managed devices must be provided by an approved organisation and the user must not have administrator access to them.
- Network rules for higher tier environments permit access only from IP ranges corresponding to `Restricted` networks that only permit managed devices to connect.
- Network rules for higher tier environments permit access only from IP ranges corresponding to **Restricted** networks that only permit managed devices to connect.

### Implication:

Expand All @@ -49,7 +49,7 @@ The set of controls applied at the Alan Turing Institute are discussed here, tog
- Medium security research spaces control the possibility of unauthorised viewing.
- Card access or other means of restricting entry to only known researchers (such as the signing in of guests on a known list) is required.
- Screen adaptations or desk partitions should be adopted in open-plan spaces if there is a high risk of unauthorised people viewing the user's screen.
- Firewall rules for the SREs only permit access from `Restricted` network IP ranges corresponding to these research spaces.
- Firewall rules for the SREs only permit access from **Restricted** network IP ranges corresponding to these research spaces.

### Implication:

Expand Down Expand Up @@ -103,7 +103,7 @@ To minimise the risk of unauthorised access to the dataset while the ingress vol
### Turing configuration setting::

- Users can write to the `/output` volume.
- A {ref}`role_system_manager` can view and download data in the `/output` volume via `Azure Storage Explorer`.
- A {ref}`role_system_manager` can view and download data in the `/output` volume via **Azure Storage Explorer**.

### Implication:

Expand Down Expand Up @@ -147,7 +147,7 @@ To minimise the risk of unauthorised access to the dataset while the ingress vol

### Turing configuration setting:

- An `Azure Firewall` ensures that all VMs within the safe haven have the minimal level of internet access required to function.
- An **Azure Firewall** ensures that all VMs within the safe haven have the minimal level of internet access required to function.

### Implication:

Expand Down
4 changes: 2 additions & 2 deletions docs/source/design/security/technical_controls.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,6 @@ Note that this means that eg. password managers cannot be used to autofill a {re

### Python/R package availability:

- **{ref}`policy_tier_3`:** A pre-agreed allowlist of packages from `CRAN` and `PyPI` (via proxy or local mirror).
- **{ref}`policy_tier_2`:** Anything on `CRAN` or `PyPI` (via proxy or local mirror).
- **{ref}`policy_tier_3`:** A pre-agreed allowlist of packages from **CRAN** and **PyPI** (via proxy or local mirror).
- **{ref}`policy_tier_2`:** Anything on **CRAN** or **PyPI** (via proxy or local mirror).
- **{ref}`policy_tier_0` and {ref}`policy_tier_1`:** Direct access to any package repository.
Loading
Loading