{
  "doc": {
    "id": "app/configure/client-certificates",
    "title": "Configure client certificates in Cypress",
    "description": "Configure certificate authority (CA) and client certificates to test mTLS (mutual TLS) protected endpoints in Cypress on a per-URL basis.",
    "section": "app",
    "source_path": "/llm/markdown/app/configure/client-certificates.md",
    "version": "066c46e056f0f322a0670d2d3aa4e6adaebfe717",
    "updated_at": "2026-09-10T13:30:12.426Z",
    "headings": [
      {
        "id": "app/configure/client-certificates#client-certificates",
        "text": "Client Certificates",
        "level": 1
      },
      {
        "id": "app/configure/client-certificates#syntax",
        "text": "Syntax",
        "level": 2
      },
      {
        "id": "app/configure/client-certificates#usage",
        "text": "Usage",
        "level": 2
      },
      {
        "id": "app/configure/client-certificates#how-certificates-are-applied",
        "text": "How Certificates Are Applied",
        "level": 2
      },
      {
        "id": "app/configure/client-certificates#testing-with-multiple-client-identities",
        "text": "Testing with multiple client identities",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#testing-mtls-protected-endpoints",
        "text": "Testing mTLS-Protected Endpoints",
        "level": 2
      },
      {
        "id": "app/configure/client-certificates#visiting-an-mtls-endpoint",
        "text": "Visiting an mTLS endpoint",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#making-api-requests-to-an-mtls-endpoint",
        "text": "Making API requests to an mTLS endpoint",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#debugging-certificate-issues",
        "text": "Debugging Certificate Issues",
        "level": 2
      },
      {
        "id": "app/configure/client-certificates#inspecting-the-cypress-log",
        "text": "Inspecting the Cypress log",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#common-errors",
        "text": "Common errors",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#using-client-certificates-in-ci",
        "text": "Using Client Certificates in CI",
        "level": 2
      },
      {
        "id": "app/configure/client-certificates#storing-certificates-securely",
        "text": "Storing certificates securely",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#adding-the-certificates-directory-to-gitignore",
        "text": "Adding the certificates directory to .gitignore",
        "level": 3
      },
      {
        "id": "app/configure/client-certificates#history",
        "text": "History",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Client Certificates"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Many enterprise, government, and regulated-industry systems require clients to present a certificate to authenticate at the TLS layer — before your application code even runs. This pattern is called mutual TLS (mTLS): unlike standard HTTPS where only the server proves its identity, mTLS requires both sides to present certificates, so the server can verify the caller is a trusted client."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Without mTLS support, you face an unpleasant choice: disable certificate requirements in your test environment (meaning your tests run against a system that doesn't match production), or rely on slow and inconsistent manual testing."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `clientCertificates` configuration lets you supply the certificates Cypress needs to authenticate against mTLS-protected endpoints, so your automated E2E tests exercise the real security boundary. Misconfigurations, expired certificates, or changed server requirements get caught in CI — not in production, where the cost is highest."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Document Scope"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This document covers how to configure certificate file paths for use in your tests. The creation and management of certificate files themselves are outside the scope of Cypress documentation."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Syntax"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "clientCertificates (Object[])"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "An array of objects defining the certificates. Each object must have the following properties"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Property"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Type"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Description"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`url`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`String`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "URL to match requests against. Wildcards following "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/isaacs/minimatch",
                    "children": [
                      {
                        "type": "text",
                        "value": "minimatch"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " rules are supported."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`ca`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`Array`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "(Optional) Paths to one or more CA files to validate certs against, relative to project root."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`certs`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`Object[]`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "A PEM format certificate/private key pair or PFX certificate container"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Each object in the `certs` array can define either a PEM format certificate/private key pair or a PFX certificate container. Both RSA and ECDSA (EC) keys are supported."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A PEM format certificate/private key pair can have the following properties:"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Property"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Type"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Description"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cert`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`String`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Path to the certificate file, relative to project root."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`key`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`String`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Path to the private key file, relative to project root."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`passphrase`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`String`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "(Optional) Path to a text file containing the passphrase, relative to project root."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A PFX certificate container can have the following properties:"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Property"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Type"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Description"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`pfx`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`String`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Path to the certificate container, relative to project root."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`passphrase`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`String`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "(Optional) Path to a text file containing the passphrase, relative to project root."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Usage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To configure CA / client certificates within your Cypress configuration, you can add the `clientCertificates` key to define an array of client certificates as shown below:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.js"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.ts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const { defineConfig } = require('cypress')\n\nmodule.exports = defineConfig({\n  clientCertificates: [\n    {\n      url: 'https://a.host.com',\n      ca: ['certs/ca.pem'],\n      certs: [\n        {\n          cert: 'certs/cert.pem',\n          key: 'certs/private.key',\n          passphrase: 'certs/pem-passphrase.txt',\n        },\n      ],\n    },\n    {\n      url: 'https://b.host.com/a_base_route/**',\n      ca: [],\n      certs: [\n        {\n          pfx: '/home/tester/certs/cert.pfx',\n          passphrase: '/home/tester/certs/pfx-passphrase.txt',\n        },\n      ],\n    },\n    {\n      url: 'https://a.host.*.com/',\n      ca: [],\n      certs: [\n        {\n          pfx: 'certs/cert.pfx',\n          passphrase: 'certs/pfx-passphrase.txt',\n        },\n      ],\n    },\n  ],\n})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'\n\nexport default defineConfig({\n  clientCertificates: [\n    {\n      url: 'https://a.host.com',\n      ca: ['certs/ca.pem'],\n      certs: [\n        {\n          cert: 'certs/cert.pem',\n          key: 'certs/private.key',\n          passphrase: 'certs/pem-passphrase.txt',\n        },\n      ],\n    },\n    {\n      url: 'https://b.host.com/a_base_route/**',\n      ca: [],\n      certs: [\n        {\n          pfx: '/home/tester/certs/cert.pfx',\n          passphrase: '/home/tester/certs/pfx-passphrase.txt',\n        },\n      ],\n    },\n    {\n      url: 'https://a.host.*.com/',\n      ca: [],\n      certs: [\n        {\n          pfx: 'certs/cert.pfx',\n          passphrase: 'certs/pfx-passphrase.txt',\n        },\n      ],\n    },\n  ],\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "How Certificates Are Applied"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress automatically applies the correct client certificate for every outgoing network request — including those initiated by "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/visit.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.visit()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/request.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.request()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " — based on URL pattern matching. No additional options need to be passed to these commands."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When Cypress makes a request, it compares the target URL against each `url` pattern in the `clientCertificates` array. If a matching entry is found, its certificates are attached to the request automatically."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If more than one entry matches the same URL, Cypress selects the entry with the most specific (longest) path pattern."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `url` field in each `clientCertificates` entry supports "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/isaacs/minimatch",
            "children": [
              {
                "type": "text",
                "value": "minimatch"
              }
            ]
          },
          {
            "type": "text",
            "value": " glob patterns (for example `https://a.host.com/api/**`), so a single entry can cover an entire path hierarchy."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Testing with multiple client identities"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress does not support passing a specific certificate to `cy.visit()` or any other command at call time. Certificate selection is always URL-pattern-based and configured statically in `clientCertificates`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your tests need to authenticate as different users against the same base URL, you can work around this limitation in a couple of ways:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": true,
        "children": [
          {
            "type": "listItem",
            "spread": true,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Distinct path patterns – If your server exposes user-specific base paths, configure a separate `clientCertificates` entry for each path pattern:"
                  }
                ]
              },
              {
                "type": "list",
                "ordered": false,
                "start": null,
                "spread": false,
                "children": [
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "cypress.config.js"
                          }
                        ]
                      }
                    ]
                  },
                  {
                    "type": "listItem",
                    "spread": false,
                    "checked": null,
                    "children": [
                      {
                        "type": "paragraph",
                        "children": [
                          {
                            "type": "text",
                            "value": "cypress.config.ts"
                          }
                        ]
                      }
                    ]
                  }
                ]
              },
              {
                "type": "code",
                "lang": null,
                "meta": null,
                "value": "const { defineConfig } = require('cypress')\n\nmodule.exports = defineConfig({\n  clientCertificates: [\n    {\n      url: 'https://example.com/users/alice/**',\n      certs: [\n        { pfx: 'certs/alice.pfx', passphrase: 'certs/alice-passphrase.txt' },\n      ],\n    },\n    {\n      url: 'https://example.com/users/bob/**',\n      certs: [{ pfx: 'certs/bob.pfx', passphrase: 'certs/bob-passphrase.txt' }],\n    },\n  ],\n})"
              },
              {
                "type": "code",
                "lang": null,
                "meta": null,
                "value": "import { defineConfig } from 'cypress'\n\nexport default defineConfig({\n  clientCertificates: [\n    {\n      url: 'https://example.com/users/alice/**',\n      certs: [\n        { pfx: 'certs/alice.pfx', passphrase: 'certs/alice-passphrase.txt' },\n      ],\n    },\n    {\n      url: 'https://example.com/users/bob/**',\n      certs: [{ pfx: 'certs/bob.pfx', passphrase: 'certs/bob-passphrase.txt' }],\n    },\n  ],\n})"
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Separate configuration files – Maintain separate Cypress configuration files (for example `cypress.alice.config.ts` and `cypress.bob.config.ts`), each specifying the appropriate `clientCertificates`, and run them as separate test suites."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Testing mTLS-Protected Endpoints"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Once `clientCertificates` is configured, Cypress attaches the correct certificate automatically. Your test code looks the same as any other E2E test — no special options are required on individual commands."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Visiting an mTLS endpoint"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// cypress/e2e/mtls.cy.js\ndescribe('mTLS-protected app', () => {\n  it('loads the dashboard', () => {\n    // Cypress attaches the client cert automatically based on the URL\n    cy.visit('https://secure.example.com/dashboard')\n    cy.get('h1').should('contain', 'Welcome')\n  })\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Making API requests to an mTLS endpoint"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/request.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.request()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " also benefits from the configured certificates, making it straightforward to test REST APIs behind mTLS:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "describe('mTLS API', () => {\n  it('returns 200 for an authenticated request', () => {\n    cy.request('GET', 'https://api.example.com/data').then((response) => {\n      expect(response.status).to.eq(200)\n    })\n  })\n\n  it('returns the expected payload', () => {\n    cy.request('POST', 'https://api.example.com/records', { name: 'test' })\n      .its('body.id')\n      .should('be.a', 'string')\n  })\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A `400 Bad Request` response (or a TLS handshake error in the Cypress log) when hitting an endpoint is the most common sign that the client certificate was not presented. Double-check that the `url` pattern in `clientCertificates` matches the full URL of your target — including any port number if the server runs on a non-standard port (e.g. `https://secure.example.com:8443/**`)."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Debugging Certificate Issues"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Inspecting the Cypress log"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When Cypress makes a request to a URL that matches a `clientCertificates` entry, it logs `clientCertificates` details in the Cypress App network panel. Open the panel and look for the lock icon next to the matching request to confirm that a certificate was attached."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Common errors"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Symptom"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Likely cause"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`400 Bad Request` from server"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Certificate not presented — URL pattern mismatch"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`SSL_ERROR_HANDSHAKE_FAILURE`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Wrong certificate, expired cert, or CA chain mismatch"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`ENOENT: no such file or directory`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Certificate file path is incorrect or relative path is wrong"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`bad decrypt` / `wrong final block length`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Passphrase file content is incorrect or has trailing whitespace"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Certificate works locally but not in CI"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Certificate files not committed or not present at the expected path in CI"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Using Client Certificates in CI"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Storing certificates securely"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Never commit unencrypted private keys to your repository. Instead, store certificate material as CI secrets and write them to disk at the start of your pipeline."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "GitHub Actions example:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "- name: Write client certificates\n  run: |\n    mkdir -p certs\n    echo \"${{ secrets.CLIENT_CERT }}\"       | base64 --decode > certs/cert.pem\n    echo \"${{ secrets.CLIENT_KEY }}\"        | base64 --decode > certs/private.key\n    echo \"${{ secrets.CLIENT_PASSPHRASE }}\" > certs/pem-passphrase.txt"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Then reference those paths in `cypress.config.ts`:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "clientCertificates: [\n  {\n    url: 'https://secure.example.com/**',\n    certs: [\n      {\n        cert: 'certs/cert.pem',\n        key: 'certs/private.key',\n        passphrase: 'certs/pem-passphrase.txt',\n      },\n    ],\n  },\n]"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Adding the certificates directory to `.gitignore`"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "# .gitignore\ncerts/"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Make sure the `certs/` directory (or whichever path you use) is in `.gitignore` so that private keys are never accidentally committed."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "History"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Version"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Changes"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/changelog.md#15-16-0",
                    "children": [
                      {
                        "type": "text",
                        "value": "15.16.0"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Added support for ECDSA (EC) keys in PEM and PFX client certificates"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/changelog.md#8-0-0",
                    "children": [
                      {
                        "type": "text",
                        "value": "8.0.0"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Added Client Certificates configuration options"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 1868
}