.gitlab-ci.yml schema broken for job:secrets

Summary

Schema for .gitlab-ci.yml disagrees with documentation (web reference, also code), CI lint and actual pipeline instances.

The schema is defined so that it expects an additional layer between job:secrets and its descendant vault and mistakenly reports for working usages one of

  • "Schema validation: Incompatible types. Required: object. Actual: string." - for "vault" with value of type string, or
  • "Schema validation: Missing required property 'vault'" - for "vault" with value of type object.

The code author agrees this is an oversight.

(Code and the bug were transferred from JSON Schema Store to GitLab in late September.)

Steps to reproduce

  1. From the documentation take the first example code for secrets, put it into .gitlab-ci.yml and add a script config (to satisfy the schema otherwise):
job:
  secrets:
    DATABASE_PASSWORD:  # Store the path to the secret in this CI/CD variable
      vault:  # Translates to secret: `ops/data/production/db`, field: `password`
        engine:
          name: kv-v2
          path: ops
        path: production/db
        field: password
  script:
    echo "foo"
  1. Have a syntax validator using the current schema, e. g. IntelliJ (mine still uses the schema from JSON Schema Store which is materially the same as the local one). Note, GitLab's CI lint does not use the schema.
    • old schema URL: https://json.schemastore.org/gitlab-ci
    • new schema URL: https://gitlab.com/gitlab-org/gitlab/-/raw/master/app/assets/javascripts/editor/schema/ci.json
  2. Validate syntax and get "Schema validation: Missing required property 'vault'"

Example Project

Basically only a .gitlab-ci.yml - gitlab-ci-secrets-schema.

What is the current bug behavior?

Syntax validator (IntelliJ) issues warnings about syntactically correct secrets configurations in .gitlab-ci.yml.

What is the expected correct behavior?

Syntax should be correctly validated.

Relevant logs and/or screenshots

Here is the problematic code. Note, there are two layers "additionalProperties" (each of type object) between "secrets" and "vault" with only the inner layer requiring a key "vault".

"secrets": {
  "type": "object",
  "additionalProperties": {
    "type": "object",
    "additionalProperties": {
      "type": "object",
      "properties": {
        "vault": {
          "oneOf": [
            {
              "type": "string",
            },
            {
              "type": "object",
            }
          ]
        }
      },
      "required": ["vault"]

This disallows

  • secrets:<name>:vault:<string-type-value> because the inner "additionalProperties" needs to be of type object.
  • secrets:<name>:vault:<object-without-key-vault> because the inner "additionalProperties" needs a key "vault".

Here are examples (same as in the project linked above) with the two allowed types for the value of "vault" each in a format where either CI lint or the schema validator disagrees and with the stated disagreement.

# job-1: No extra layer, "vault" with value of type object
# Schema disagrees, CI linter agrees
# Warning: "Schema validation: Missing required property 'vault'"
job-1:
  secrets:
    DATA_FILE:
      vault:
        engine:
          name: kv-v2
          path: ops
        path: production/db
        field: some_data
  script:
    cat $DATA_FILE

# job-2: With extra layer "some_name", "vault" with value of type object
# Schema agrees, CI linter disagrees
# Warnings:
# - "jobs:job-2:secrets:data_file config contains unknown keys: some_name"
# - "jobs:job-2:secrets:data_file config missing required keys: vault"
job-2:
  secrets:
    DATA_FILE:
      some_name:
        vault:
          engine:
            name: kv-v2
            path: ops
          path: production/db
          field: some_data
  script:
    cat $DATA_FILE

# job-3: No extra layer, "vault" with value of type string
# Schema disagrees, CI linter agrees
# Warning: "Schema validation: Incompatible types. Required: object. Actual: string."
job-3:
  secrets:
    DATA_FILE:
      vault: production/db/some_data@ops
  script:
    cat $DATA_FILE

# job-4: With extra layer "some_name", "vault" with value of type string
# Schema agrees, CI linter disagrees
# Warnings:
# - "jobs:job-4:secrets:data_file config contains unknown keys: some_name
# - "jobs:job-4:secrets:data_file config missing required keys: vault"
job-4:
  secrets:
    DATA_FILE:
      some_name:
        vault: production/db/some_data@ops
  script:
    cat $DATA_FILE

Possible fixes

Remove the outer "additionalProperties" (which does not require key "vault") from the problematic code.

"secrets": {
  "type": "object",
  "additionalProperties": {    # Remove!
    "type": "object",          # Remove!
    "additionalProperties": {
      "type": "object",
      "properties": {
        "vault": {
          "oneOf": [
            {
              "type": "string",
            },
            {
              "type": "object",
            }
          ]
        }
      },
      "required": ["vault"]
    }
  }                            # Remove!
},

The code author links to approaches to testing this and surrounding code because, of course, a fix should come with tests. Links repeated here:

  • #345238 (closed)
  • #344894 (closed)
  • #218473 (closed)
Assignee Loading
Time tracking Loading