Skip to content

Connecting your pipeline

Connecting an application to cDSO means adding two things to the application's own GitLab repository: an include in .gitlab-ci.yml and a cdso_config.yml at the root. There is nothing to install on your machine, and the way you build does not change.

1. Include the review component

Add the cDSO review component to .gitlab-ci.yml. It owns the stage list and the workflow rules, builds the image in the build stage, and provides the manual scans job in the review stage.

include:
  - project: ulap/alex/r2d2/cdsov2/cdso
    ref: main
    file:
      - templates/review.yml
    inputs:
      name: "my-service"
      cdso_branch: main
      pipeline_type: "application-container"
Input What to put
name The container name. Must match the top level key you use in cdso_config.yml.
cdso_branch Should match ref.
pipeline_type application-container for a service you deploy. Other values: base-container, tool-container, environment, sdd, or none.

The component defines these stages: pre-build, pre-test, build, post-test, review, clean, deliver. Your own jobs slot into them. A test job belongs in pre-test; a deploy that should never wait on the scans belongs in post-test.

The component's before_script

The component sources a generated .env in its global before_script. If a job of yours needs a clean environment, override it with before_script: [].

2. Add cdso_config.yml

At the repository root, one file the pipeline reads and the reviewer sees.

deployment_level: "PRODUCTION"   # DEVELOPMENT, STAGING, PRODUCTION
security_group: "acme"           # the reviewing security group
organization: "acme"
software_name: "my-service"      # filing directory in the security group's scans project

# must match the `name` input on the review component
my-service:
  project_type: "container"      # container, tool, base
  dockerfile_folder: "."
  container_lifespan: "PERSISTENT"   # or EPHEMERAL
  connection_context: "EXTERNAL"     # internet facing, or INTERNAL

Per scan blocks (mitigations, false positives, exclusions, justifications) are added under the container key once the first scan has reported. See cdso_config.yml for every field.

deployment_level changes the policy

The container spec gate depends on deployment_level. A root user passes at DEVELOPMENT and fails at PRODUCTION. Set the level to where the container will actually run.

3. Push and check Attest

Commit both files and push. The pipeline builds. Open attest.ulapcybo.app and find the container under My applications. Until the first scan has reported, it shows as awaiting its first scan.

Where the evidence goes

Scan output publishes to the security repository for your security group, under cdsov2/security/<security_group>/<software_name>. The security repository is Ulap managed infrastructure; your application repository is never written to by the pipeline. The review merge request opens in the security repository, and everything Attest shows you is read from there.

Attest runs on GitLab

Everything in this process runs on GitLab: the pipeline component, the security repository, the review merge request, and the reviewer's approval. If your code lives on another platform, the Program plan can stand up a GitLab instance inside your environment that mirrors your repositories and hosts the security repository and reviews, while the rest of your toolchain stays where it is. Write to contact@ulap.co if that is your situation.

Onboarding is a manual step on purpose

Attest can generate a cdso_config.yml for you, but committing it and adding the include is something a person does in your repository. The token Attest uses to read your fleet has no write access to anything.