Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cli/environment-variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ For storing and securing environment variables, we advise the following:

1. Store local environment variables in your shell or in `.env` files that are not committed to your git repo. Add those
files to your `.gitignore` file.
2. In a CI context, e.g. GitHub Actions, store sensitive variables as secrets. Almost all CI providers have such a feature.
2. In a CI context, load sensitive values from your CI secret store or an external secrets manager. For large secret sets, see [Manage secrets at scale](/platform/manage-secrets-at-scale).
3. For remote variables, store sensitive data as secrets in Checkly. For more information on how to manage secrets in Checkly see [variables and secrets](/platform/variables).

All variables are stored encrypted at rest and in transfer.
17 changes: 12 additions & 5 deletions constructs/browser-check.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ new BrowserCheck("browser-check-1", {

```ts Advanced Example
import { BrowserCheck, Frequency } from "checkly/constructs"
import { secret } from "checkly/util"
import * as path from "path"

new BrowserCheck("advanced-browser-check", {
Expand All @@ -52,7 +53,7 @@ new BrowserCheck("advanced-browser-check", {
runtimeId: "2025.04",
environmentVariables: [
{ key: "TEST_USERNAME", value: "testuser" },
{ key: "TEST_PASSWORD", value: "{{SECRET_PASSWORD}}", secret: true },
{ key: "TEST_PASSWORD", value: secret("TEST_PASSWORD"), secret: true },
],
code: {
entrypoint: path.join(__dirname, "advanced-flow.spec.ts"),
Expand Down Expand Up @@ -167,14 +168,16 @@ new BrowserCheck("quick-test", {
```

```ts Complex Test File
import { secret } from "checkly/util"

new BrowserCheck("e2e-purchase", {
name: "E-commerce Purchase Flow",
code: {
entrypoint: path.join(__dirname, "tests/purchase-flow.spec.ts"),
},
environmentVariables: [
{ key: "TEST_USER_EMAIL", value: "test@example.com" },
{ key: "TEST_PASSWORD", value: "{{SECRET_PASSWORD}}", secret: true },
{ key: "TEST_PASSWORD", value: secret("TEST_PASSWORD"), secret: true },
],
})
```
Expand Down Expand Up @@ -379,12 +382,14 @@ Check-level environment variables that will be available during test execution.

**Usage:**

```ts highlight={3-6}
```ts highlight={5-8}
import { secret } from "checkly/util"

new BrowserCheck("my-check", {
name: "My Browser Check",
environmentVariables: [
{ key: "TEST_USERNAME", value: "testuser@example.com" },
{ key: "TEST_PASSWORD", value: "{{SECRET_PASSWORD}}", secret: true },
{ key: "TEST_PASSWORD", value: secret("TEST_PASSWORD"), secret: true },
],
/* More options... */
})
Expand All @@ -403,11 +408,13 @@ new BrowserCheck("my-check", {
<CodeGroup>

```ts Test Credentials
import { secret } from "checkly/util"

new BrowserCheck("user-flow", {
name: "User Account Flow",
environmentVariables: [
{ key: "TEST_EMAIL", value: "test@example.com" },
{ key: "TEST_PASSWORD", value: "{{TEST_USER_PASSWORD}}", secret: true },
{ key: "TEST_PASSWORD", value: secret("TEST_PASSWORD"), secret: true },
{ key: "BASE_URL", value: "https://staging.example.com" },
],
code: { entrypoint: path.join(__dirname, "user-flow.spec.ts") },
Expand Down
4 changes: 2 additions & 2 deletions constructs/check-group-v2.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ new ApiCheck("api-check-1", {

```ts Advanced Example
import { ApiCheck, CheckGroupV2, EmailAlertChannel, Frequency } from "checkly/constructs"
import { secret } from "checkly/util"

const emailChannel = new EmailAlertChannel("team-email", {
address: "team@example.com",
Expand All @@ -54,7 +55,7 @@ const group = new CheckGroupV2("comprehensive-group", {
concurrency: 5,
environmentVariables: [
{ key: "API_BASE_URL", value: "https://api.example.com" },
{ key: "API_KEY", value: "{{SECRET_API_KEY}}", secret: true },
{ key: "API_KEY", value: secret("API_KEY"), secret: true },
],
alertChannels: [emailChannel],
browserChecks: {
Expand Down Expand Up @@ -389,4 +390,3 @@ See [Mixing Checks and Monitors in a Group](/platform/groups/#mixing-checks-and-
```
</Tab>
</Tabs>

3 changes: 2 additions & 1 deletion constructs/check-group.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
EmailAlertChannel,
Frequency,
} from "checkly/constructs"
import { secret } from "checkly/util"

const emailChannel = new EmailAlertChannel("team-email", {
address: "team@example.com",
Expand All @@ -59,7 +60,7 @@ const group = new CheckGroup("comprehensive-group", {
concurrency: 5,
environmentVariables: [
{ key: "API_BASE_URL", value: "https://api.example.com" },
{ key: "API_KEY", value: "{{SECRET_API_KEY}}", secret: true },
{ key: "API_KEY", value: secret("API_KEY"), secret: true },
],
alertChannels: [emailChannel],
browserChecks: {
Expand Down
3 changes: 2 additions & 1 deletion constructs/multistep-check.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ new MultiStepCheck("multistep-check-1", {

```ts Advanced Example
import { MultiStepCheck, Frequency } from "checkly/constructs"
import { secret } from "checkly/util"
import * as path from "path"

new MultiStepCheck("complex-multistep-check", {
Expand All @@ -52,7 +53,7 @@ new MultiStepCheck("complex-multistep-check", {
environmentVariables: [
{ key: "BASE_URL", value: "https://app.example.com" },
{ key: "TEST_USER_EMAIL", value: "test@example.com" },
{ key: "TEST_USER_PASSWORD", value: "{{SECRET_PASSWORD}}", secret: true },
{ key: "TEST_USER_PASSWORD", value: secret("TEST_USER_PASSWORD"), secret: true },
],
code: {
entrypoint: path.join(__dirname, "user-journey.spec.ts"),
Expand Down
10 changes: 7 additions & 3 deletions constructs/playwright-check.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,15 @@ Check-level environment variables that will be available during test execution.

**Usage:**

```ts highlight={4-7}
```ts highlight={6-9}
import { secret } from "checkly/util"

new PlaywrightCheck("user-flow-pwt-check-suite", {
name: "User Flow Playwright Check Suite",
playwrightConfigPath: "../playwright.config.ts",
environmentVariables: [
{ key: "TEST_USERNAME", value: "testuser@example.com" },
{ key: "TEST_PASSWORD", value: "{{SECRET_PASSWORD}}", secret: true },
{ key: "TEST_PASSWORD", value: secret("TEST_PASSWORD"), secret: true },
],
})
```
Expand All @@ -484,12 +486,14 @@ new PlaywrightCheck("user-flow-pwt-check-suite", {
<CodeGroup>

```ts Test Credentials
import { secret } from "checkly/util"

new PlaywrightCheck("user-flow-pwt-check-suite", {
name: "User Flow Playwright Check Suite",
playwrightConfigPath: "../playwright.config.ts",
environmentVariables: [
{ key: "TEST_USERNAME", value: "testuser@example.com" },
{ key: "TEST_PASSWORD", value: "{{SECRET_PASSWORD}}", secret: true },
{ key: "TEST_PASSWORD", value: secret("TEST_PASSWORD"), secret: true },
],
})
```
Expand Down
12 changes: 11 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
]
},
"platform/secrets",
"platform/manage-secrets-at-scale",
"platform/dynamic-secret-scrubbing",
"platform/data-storage",
"platform/variables",
Expand Down Expand Up @@ -434,7 +435,16 @@
"group": "GitHub",
"pages": [
"integrations/ci-cd/github/actions",
"integrations/ci-cd/github/deployments"
"integrations/ci-cd/github/deployments",
{
"group": "External secrets",
"pages": [
"integrations/ci-cd/github/secrets/aws-secrets-manager",
"integrations/ci-cd/github/secrets/google-secret-manager",
"integrations/ci-cd/github/secrets/azure-key-vault",
"integrations/ci-cd/github/secrets/hashicorp-vault"
]
}
]
},
"integrations/ci-cd/gitlab/overview",
Expand Down
1 change: 1 addition & 0 deletions integrations/ci-cd/github/actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -250,4 +250,5 @@ If the workflow uses path filters, make sure it still creates the required Check

- Learn more about [`checkly test`](/cli/checkly-test).
- Learn more about [`checkly trigger`](/cli/checkly-trigger).
- [Deploy scoped Checkly secrets from an external secrets manager](/platform/manage-secrets-at-scale).
- Use [GitHub deployment hooks](/integrations/ci-cd/github/deployments) when you want Checkly to react directly to GitHub deployment events.
140 changes: 140 additions & 0 deletions integrations/ci-cd/github/secrets/aws-secrets-manager.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
title: "Deploy Checkly secrets from AWS Secrets Manager"
sidebarTitle: "AWS Secrets Manager"
description: "Use GitHub Actions and OIDC to deploy scoped Checkly secrets from AWS Secrets Manager."
canonical: "https://www.checklyhq.com/docs/integrations/ci-cd/github/secrets/aws-secrets-manager/"
---

Use GitHub OpenID Connect (OIDC) to obtain short-lived AWS credentials, read the secrets required by one Checkly CLI project, and deploy them as group- or check-level secrets. For the architecture and scoping model, see [Manage secrets at scale](/platform/manage-secrets-at-scale).

<Accordion title="Prerequisites">
- A Checkly CLI project with `checkly` installed as a dependency.
- An AWS account with your values stored in AWS Secrets Manager.
- A GitHub repository with Actions enabled.
- A protected GitHub environment named `checkly-production`. Restrict its deployment branches and reviewers as appropriate.
- The repository or environment variables `AWS_ROLE_ARN`, `AWS_REGION`, and `CHECKLY_ACCOUNT_ID`.
- Permission to create an AWS IAM OIDC provider and role.
</Accordion>

<Info>
This guide uses a fictional payments service; replace its names, paths, and
URL with your own application values. Checkly requires `CHECKLY_API_KEY` and
`CHECKLY_ACCOUNT_ID`; `AWS_ROLE_ARN` and `AWS_REGION` configure this workflow.
</Info>

## Configure AWS access

Follow AWS's guide for [using Secrets Manager in GitHub jobs](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets_github.html) to create an OIDC provider and IAM role. Restrict the role's trust policy to the repository and protected GitHub environment that deploy Checkly.

Grant the role `secretsmanager:GetSecretValue` only for the secrets listed in this workflow. The retrieval action also requires `secretsmanager:ListSecrets`; secrets encrypted with a customer-managed KMS key require `kms:Decrypt` on that key. Store the role ARN and region in `AWS_ROLE_ARN` and `AWS_REGION` GitHub Actions variables.

## Scope secrets in your constructs

Use `secret()` to read `CHECKLY_SECRET_*` from the deploy process. Set `secret: true` so Checkly stores the value as a non-retrievable secret. Attach each value at the narrowest level that needs it:

```typescript checks/payments.check.ts
import { ApiCheck, CheckGroupV2, Frequency } from "checkly/constructs";
import { secret } from "checkly/util";

const paymentsGroup = new CheckGroupV2("payments", {
name: "Payments",
activated: true,
muted: false,
frequency: Frequency.EVERY_10M,
locations: ["us-east-1"],
environmentVariables: [
{
key: "PAYMENTS_API_KEY",
value: secret("PAYMENTS_API_KEY"),
secret: true,
},
],
});

new ApiCheck("payments-admin-api", {
name: "Payments admin API",
group: paymentsGroup,
environmentVariables: [
{
key: "PAYMENTS_ADMIN_TOKEN",
value: secret("PAYMENTS_ADMIN_TOKEN"),
secret: true,
},
],
request: {
method: "GET",
url: "https://payments.example.com/admin/health",
headers: [
{ key: "Authorization", value: "Bearer {{PAYMENTS_API_KEY}}" },
{ key: "X-Admin-Token", value: "{{PAYMENTS_ADMIN_TOKEN}}" },
],
},
});
```

`secret('PAYMENTS_API_KEY')` reads `CHECKLY_SECRET_PAYMENTS_API_KEY` during deployment and fails if it is missing. The shorter key `PAYMENTS_API_KEY` is what your check receives at runtime.

## Fetch and deploy in GitHub Actions

Fetch each AWS secret with an explicit `CHECKLY_SECRET_*` alias. The retrieval action masks the values and adds them to the environment of subsequent steps.

```yaml .github/workflows/checkly-deploy.yml
name: Deploy Checkly

on:
push:
branches: [main]
workflow_dispatch:

jobs:
deploy:
runs-on: ubuntu-latest
environment: checkly-production
permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v7

- uses: actions/setup-node@v7
with:
node-version: 22
cache: npm

- name: Install dependencies
run: npm ci

- name: Authenticate to AWS
uses: aws-actions/configure-aws-credentials@v6
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: ${{ vars.AWS_REGION }}
allowed-account-ids: "123456789012"
mask-aws-account-id: true
role-session-name: checkly-${{ github.run_id }}

- name: Fetch deployment secrets
uses: aws-actions/aws-secretsmanager-get-secrets@v3
with:
secret-ids: |
CHECKLY_API_KEY, checkly/production/api-key
CHECKLY_SECRET_PAYMENTS_API_KEY, checkly/production/payments-api-key
CHECKLY_SECRET_PAYMENTS_ADMIN_TOKEN, checkly/production/payments-admin-token

- name: Deploy Checkly
env:
CHECKLY_ACCOUNT_ID: ${{ vars.CHECKLY_ACCOUNT_ID }}
run: npx checkly deploy --force
```

Install dependencies before fetching secrets, and keep deployment as the final step. Values created by `aws-secretsmanager-get-secrets` are available to every later step in the job, not only the deploy command.

<Warning>
Do not print or persist fetched values. Keep deployment as the final step that
receives them.
</Warning>

## Rotate a secret

When you rotate a value in AWS Secrets Manager, run this workflow again. Checkly receives a copy during `checkly deploy`; rotation in AWS does not update an already deployed Checkly secret automatically.
Loading
Loading