Skip to main content

The DfE technical guidance and its content is intended for internal use by the DfE community.

Azure CIP

It provides preconfigured Azure subscriptions including security guardrails.

It provides access to most Azure resources including App Services, Container Instances, Virtual Networks, managed databases, Front Door, Key Vault, storage accounts, etc.


Platform documentation

Onboarding users

Use this service portal form to create the onboarding request:

  1. From Request type dropdown, select: Azure Portal and DevOps User Account Request
  2. From Add/Change/Remove dropdown, select: Add
  3. Enter new users’ email addresses

If access to the service portal is not possible, ask the helpdesk (See Support) to “Invite –username– to the CIP AAD. FAO of the Infrastructure Operations Team”

Ask in #cloud-platform on Slack if more help is required.

The new user will receive an invitation by email. Then the service administrators can add them to the service Azure Active Directory groups of the subscriptions: Managers and Delivery team.

To access Azure DevOps, the new user must access the Azure DevOps CIP instance. This will register them in the system then the service administrator can add them to the project.

Privileged Identity Management (PIM) Requests

Privileged Identity Management (PIM) is a service in Azure Active Directory (Azure AD) that enables you to manage, control, and monitor access to important resources at DfE such as access to staging and production environments.

To request access to your eligible assignments, follow the steps below:

  • Navigate to the Azure Portal and login using the email you registered with your CIP account

  • Click on Directories + subscriptions, this is the icon to the left of the notification bell icon in the blue navigation bar

  • Ensure you are in the DfE Platform Identity directory, if you are not, switch to it. You may be prompted to verify your identity with 2FA

  • Search for PIM in the search bar at the top of the page and select Azure AD privileged Identity Management

  • Click on My roles on the left hand side of the page, under Tasks

  • Click on Azure resources under Activate

  • You may have to lengthen the resource section in order to see the full resource name, including the environment

  • Click Activate under Action for the relevant resource

  • Select a duration (maximum 8 hours), enter a reason for the request and click Activate

  • The test subscription, which usually includes the staging and preprod environments is self approving and you should see your request approved shortly

  • An email will be sent to the administrators for the production subscription, they will then be able to approve or deny the request. There can sometimes be a delay with this email, however an administrator can navigate to PIM using the search box (as documented above), then click Approve requests and Azure resources. The administrator should then see the request

Onboarding a service

Use this service portal form to create the onboarding request and choose Request type: On-Boarding request. It should be filled in by a senior civil servant (G7 or above). This includes an onboarding form to attach. Finance must be agreed beforehand.

You will be given:

  • 2 default subscriptions: dev and test
  • 3 Active directory groups: Reader (read only), Delivery team (developers) and Managers (can approve PIM requests). The original requestor will be owner of these groups.
  • PIM (Privileged Identity Management) set up: members of the Delivery team can elevate their access themselves in staging, and request approval from a Manager in production.
  • A new project in Azure DevOps dfe-ssp organisation and corresponding service connections to the subscriptions

The production subscription can be requested via the same service portal form. Choose Request type: Request production subscription.

Provisioned Azure DevOps

This is the default platform for automation and continuous integration in DfE: see.

When a service is onboarded to CIP, an Azure DevOps project is automatically provided, including service connection to the CIP subscription.

Azure Development

Deployments should always be done via infrastructure as code. We recommend using Terraform or ARM templates.

Access from/to Internet

Static public IPs are not permitted by default in CIP. Instead, Azure provides unique domain names but the IP may change.

Should you require a static IP, it is possible to request an Internet Access Service. It provides routing from/to the internet via a static IP and a firewall. URLs accessed via the firewall must be whitelisted.

Contact #cloud-platform to set it up.

Azure service principal

To be able to access Azure from an external system like Github actions, a service account is required. It is called a service principal in Azure. See the Azure documentation.

Create service principal

In this example we create a service principal which has Contributor (full access) including Keyvault. It depends on the custom role created in Managing secrets.

Submit a CIP Request on Service Now using your identity. The request type is Any Other Request and in Any other request description enter the following:

We have a new service called [service-name] that we are currently setting up for Teacher Services Digital team. This service will need service principals with Contributor access to [subscription-number] subscriptions so that it is in line with our deployment approach for new services.

The Service Principals will all need the Directory.Read.All Microsoft Graph API Application permission, this will need to be approved by a Domain Admin.

The Service Principals will all need the following Azure resource permissions:
Service Principal Name: Azure Resource Permissions
[dev-subscription-prefix]-[service-abbreviation]-contributor: Contributor, Key Vault Reader and Key Vault Secrets Officer roles on subscription [dev-subscription-name]
[test-subscription-prefix]-[service-abbreviation]-contributor: Contributor, Key Vault Reader and Key Vault Secrets Officer roles on subscription [test-subscription-name]
[prod-subscription-prefix]-[service-abbreviation]-contributor: Contributor, Key Vault Reader and Key Vault Secrets Officer roles on subscription [prod-subscription-name]

They will be used to deploy Azure resources from GitHub repository DFE-Digital/[repo-name] owned by DFE-Digital.

Please can you also add the following users as Owners on the Service Principals: [digital-accounts-for-infra-team-members]

Substitute anything in square brackets with values relevant to your request.

  • Create access keys with 1 year expiration. This is mandated by CIP.
  • This is the only time you will see the key, so take this opportunity to COPY and PASTE it into the Key Vault now, in a secret named SP-Readonly-Credentials for instance

Add permissions

Add the service principal to groups or access policies to give it access to particular resources.

To assign it a role, request CIP to add them. You may need approval from Security, ie the allocated ISO.

Use the service principal in external systems

The following values are required for the external system to authenticate against the service principal:

  • clientId: From App registration overview that we are creating the secret for, use the Application (client) ID
  • clientSecret: Access key generated above, retrieve it from the key vault secret (e.g. SPReadonlyCredentials) or update it if renewing the secret
  • subscriptionId: Get the subscription id at the subscription level
  • tenantId: From App registration overview, use Directory (tenant) ID

To simplify, you can use the new_aad_app_secret script to generate a formatted json with the required information as per the example below.


Before running the script:

  • Ensure you are logged in to the tenant containing the app registration and have selected the subscription which contains the resources that the app registration needs access to
  • Ensure you a member of the app registration’s ‘Owners’
  • Obtain the Application (client) ID of the app registration you want to add to the GitHub secret

Run the script with ./ <CLIENT_ID> "<DISPLAY_NAME>"

  • CLIENT_ID is the Application (client) ID from the app registration overview screen
  • DISPLAY_NAME is the credential display name (docs) in the app registration’s Certificates & secrets blade. Since a service principal may have multiple secrets, it should uniquely identify where it is used, such as: <SERVICE_NAME>-<ENVIRONMENT> (e.g. register-production)

It should then output the required information as formatted JSON. This can be pasted in as the value for the GitHub secret for example.

GitHub Actions

The credentials may be used in Github actions for the workflow to connect to Azure. As a standard, create a AZURE_CREDENTIALS secret containing the json string.

When using multiple Github deployment environments, each one may require its own set of credentials from different service principals. Configure AZURE_CREDENTIALS as environment secret for each Github environment and make sure the job is configured with the corresponding environment.

  - uses: Azure/login@v1
      creds: ${{ secrets.AZURE_CREDENTIALS }}
  - name: Set ARM environment variables
    uses: DFE-Digital/github-actions/set-arm-environment-variables@master
      azure-credentials: ${{ secrets.AZURE_CREDENTIALS }}
  terraform {
    backend "azurerm" {}
  - name: Set ARM environment variables
    uses: DFE-Digital/github-actions/set-arm-environment-variables@master
      azure-credentials: ${{ secrets.AZURE_CREDENTIALS }}
  provider "azurerm" {
    features {}


In Github actions, use the ARM variables as described above.

The json may also be passed as a terraform variable. Then the jsondecode function can be used to extract the values and configure the provider explicitly.

Access key expiration

The Operations team will alert you to the prospect of these secrets expiring, but will not update the credentials. If GitHub actions are used for example and the GitHub secret is not updated, then there is a risk of the CI/CD pipelines failing.

See above to recreate the access keys and make sure to update them in key vault and in the systems using them.

For more control there is a github_action developed to enable periodic checks.

For the GitHub action to work, the API Permission Microsoft Graph Directory.Read.All needs to be granted in App Registrations. Request the CIP team to add the permissions.