Stop a release until its privacy review is approved

Add one step to your CI/CD pipeline that fails unless the release passed its privacy-by-design review in Izini.

About 15 minutes

Under privacy by design and by default, a change that affects personal data should be reviewed before it ships. Izini's DPbDD Gateways desk records that review and, once your DPO approves it, seals it. This guide adds a pipeline step that asks Izini whether a release is approved, and stops the deployment if it is not.

You need: a project API key, and a review in Risk & Incidents > DPbDD Gateways for the release.

1. Name the review after the release

Each review has a release reference. Set it to the name your pipeline already knows the release by, such as the Git tag (v2.4.0). Then the pipeline can ask about its own release without any extra setting.

The review lets a release through once the DPO's decision is approved or approved with conditions (and stays releasable once marked released). Saving an approved review gives it a SHA-256 seal.

2. Store the key in your CI

Add a project API key as a secret named IZINI_API_KEY. Create one under Administration > Developers > API keys. A test key works too, which is handy while you set this up.

3. Add the step

The step fails when anything is wrong: no review with that reference (404), a bad key (401), or a review that is not approved (allowed is false).

GitHub Actions

yaml
jobs:
  privacy-gate:
    runs-on: ubuntu-latest
    steps:
      - name: Check the release against its privacy review
        env:
          IZINI_API_KEY: ${{ secrets.IZINI_API_KEY }}
          RELEASE_REF: ${{ github.ref_name }}   # the tag, e.g. v2.4.0
        run: |
          curl -sf -X POST https://app.izini.ng/api/v1/gateway/dpbdd/verify \
            -H "Authorization: Bearer $IZINI_API_KEY" \
            -H "Content-Type: application/json" \
            -d "{\"releaseReference\": \"$RELEASE_REF\"}" \
            | jq -e '.allowed' > /dev/null

  deploy:
    needs: privacy-gate
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploy here"

jq is already on GitHub's Ubuntu runners.

GitLab CI

yaml
privacy-gate:
  stage: test
  image: alpine:3.20
  before_script:
    - apk add --no-cache curl jq
  script:
    - >
      curl -sf -X POST https://app.izini.ng/api/v1/gateway/dpbdd/verify
      -H "Authorization: Bearer $IZINI_API_KEY"
      -H "Content-Type: application/json"
      -d "{\"releaseReference\": \"$CI_COMMIT_TAG\"}"
      | jq -e '.allowed' > /dev/null
  rules:
    - if: $CI_COMMIT_TAG

Add IZINI_API_KEY under Settings > CI/CD > Variables, masked.

Any other pipeline

The step is one shell command; any runner with curl and jq can run it:

sh
curl -sf -X POST https://app.izini.ng/api/v1/gateway/dpbdd/verify \
  -H "Authorization: Bearer $IZINI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"releaseReference\": \"$RELEASE_REF\"}" \
  | jq -e '.allowed' > /dev/null

curl -f fails on any error status and jq -e fails when allowed is not true, so the command's exit code is the answer.

4. Optional: pin the seal

To make sure the release you ship is the one that was approved, send the seal too. Copy it from the approved review in Izini into a CI variable, and add it to the request:

sh
-d "{\"releaseReference\": \"$RELEASE_REF\", \"seal\": \"$IZINI_RELEASE_SEAL\"}"

If the review is changed and approved again for a different scope, it gets a new seal, and the old one no longer passes.

5. See why a release was stopped

Drop > /dev/null to print Izini's answer in the job log:

json
{
  "allowed": false,
  "status": "controls_under_validation",
  "seal": null,
  "sealedAt": null,
  "conditions": [],
  "message": "Release not approved (status: controls_under_validation)"
}

When a release was approved with conditions, conditions lists them, so the job log shows what was agreed.

The full request and response are in the API reference.