diff --git a/.vitepress/components/Navbar.vue b/.vitepress/components/Navbar.vue index df60bba..0e86f1f 100644 --- a/.vitepress/components/Navbar.vue +++ b/.vitepress/components/Navbar.vue @@ -57,6 +57,7 @@ const isActive = (link: string) => { padding-left: 32px; display: flex; align-items: center; + z-index: 100 !important; } .second-navbar-container { diff --git a/.vitepress/sidebars/app/tutorials.ts b/.vitepress/sidebars/app/tutorials.ts index eee59fd..ddcdeed 100644 --- a/.vitepress/sidebars/app/tutorials.ts +++ b/.vitepress/sidebars/app/tutorials.ts @@ -23,6 +23,19 @@ export const tutorialsSidebar: DefaultTheme.SidebarItem[] = [ }, ], }, + { + text: "Automatisation", + items: [ + { + text: "Orchestrating Caido headless", + link: "/app/tutorials/headless_orchestration", + }, + { + text: "Running Caido in Github Actions", + link: "/app/tutorials/github_action", + }, + ], + }, { text: "Proxying Mobile Traffic", items: [ diff --git a/src/_images/github_action_secrets.png b/src/_images/github_action_secrets.png new file mode 100644 index 0000000..c882353 Binary files /dev/null and b/src/_images/github_action_secrets.png differ diff --git a/src/app/tutorials/github_action.md b/src/app/tutorials/github_action.md new file mode 100644 index 0000000..b12d21e --- /dev/null +++ b/src/app/tutorials/github_action.md @@ -0,0 +1,252 @@ +--- +description: "Learn how to orchestrate Caido in Github Action for CICD" +--- + +# Using Caido in GitHub Actions + +This tutorial will guide you through setting up and using Caido in a GitHub Actions CI/CD pipeline. You'll learn how to: + +- Set up a headless Caido instance in GitHub Actions +- Configure secrets for secure authentication +- Create scripts to interact with your Caido instance + + +This tutorial requires a Caido Teams plan for registration key support. + + +## Part 1: Creating a Registration Key + +To safely deploy Caido instances in automated environments without human intervention, you'll need to use a [Registration Key](/dashboard/concepts/registration_key). Registration keys automatically claim new instances, ensuring they're secure even when deployed in CI/CD pipelines. + +### Creating a Registration Key + +First, create a registration key in the [Caido Dashboard](https://dashboard.caido.io): + +1. Navigate to your `Team` workspace +2. Go to the Registration Keys section +3. Click `Create Key` +4. Configure the key: + - **Description**: `CI/CD Pipeline` + - **Prefix**: `cicd` (or your preferred prefix) + - **Expiration**: Set an expiration date appropriate for your use case + - **Reusable**: Yes (recommended for CI/CD) + +For detailed instructions, see our guide on [creating a registration key](/dashboard/guides/create_registration_key). + +## Part 2: Creating a Personal Access Token (PAT) + +To authenticate your scripts with the Caido instance, you'll need a [Personal Access Token (PAT)](/dashboard/concepts/pat). PATs allow headless authentication without requiring browser interaction. + +### Creating a PAT + +1. Visit the [Caido Dashboard](https://dashboard.caido.io) +2. Navigate to the Developer page **in your Workspace** +3. Click `+ Create Token` +4. Configure the token: + - **Name**: `CI/CD Automation` + - **Resource Owner**: Select your `Team` + - **Expiration**: Set an expiration date + +For detailed instructions, see our guide on [creating a PAT](/dashboard/guides/create_pat). + +## Part 3: Configuring GitHub Secrets + +To securely store your registration key and PAT, you'll need to add them as GitHub repository secrets. This ensures they're encrypted and only accessible to your GitHub Actions workflows. + +### Adding Secrets to Your Repository + +1. Navigate to your GitHub repository +2. Go to **Settings** → **Secrets and variables** → **Actions** +3. Click **New repository secret** +4. Add the following secrets: + + - **Name**: `CAIDO_REGISTRATION_KEY` + - **Value**: Your registration key (e.g., `ckey_xxxxx`) + + - **Name**: `CAIDO_PAT` + - **Value**: Your Personal Access Token (e.g., `caido_xxxxx`) + +GitHub Actions repository secrets configuration. + +::: warning +Never commit secrets directly in your code or workflow files. Always use GitHub Secrets for sensitive information. +::: + +## Part 4: Creating the Automation Script + +Now we'll create a script that uses the `@caido/sdk-client` to interact with your Caido instance. This script will demonstrate common CI/CD use cases like creating projects, running scans, and checking results. + +### Setting Up the Project + +First, create a directory for your automation scripts and initialize it: + +```bash +mkdir script +cd script +pnpm init +``` + +Install the Caido SDK client: + +```bash +pnpm install @caido/sdk-client +``` + +### The Automation Script + +Create a file named `index.ts`: + +```typescript +import { Client } from "@caido/sdk-client"; + +async function main() { + // Get the Caido instance URL from environment or use default + const instanceUrl = + process.env["CAIDO_INSTANCE_URL"] ?? "http://localhost:8080"; + + // Get the Personal Access Token from environment + const pat = process.env["CAIDO_PAT"]; + if (pat === undefined || pat === "") { + console.error("❌ Error: CAIDO_PAT environment variable is required"); + console.error(" Set it with: export CAIDO_PAT=caido_xxxxx"); + process.exit(1); + } + + const client = new Client({ + url: instanceUrl, + auth: { + pat: pat, + cache: { + file: ".secrets.json", + }, + }, + }); + + await client.connect(); + console.log("✅ Connected to Caido instance"); + + const viewer = await client.user.viewer(); + console.log("Viewer: ", JSON.stringify(viewer, null, 2)); +} + +main().catch((error: unknown) => { + console.error("❌ Fatal error:", error); + process.exit(1); +}); +``` + +### Adding Scripts to package.json + +Add the following to your `package.json`: + +```json +{ + "scripts": { + "test": "node index.ts" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "typescript": "^5.3.0" + } +} +``` + +## Part 5: Creating the GitHub Actions Workflow + +Now we'll create a GitHub Actions workflow that sets up Caido and runs your automation script. + +### Workflow File + +Create `.github/workflows/caido-tests.yml`: + +```yaml +name: Run Caido Security Scan +on: + push: + branches: + - 'main' + +jobs: + scan: + runs-on: ubuntu-latest + + services: + caido: + image: caido/caido:latest + ports: + - 8080:8080 + env: + CAIDO_REGISTRATION_KEY: ${{ secrets.CAIDO_REGISTRATION_KEY }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v6 + + - name: Set up Node + uses: actions/setup-node@v6 + with: + node-version: '24' + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 10 + + - name: Install script dependencies + working-directory: script + run: pnpm install + + - name: Run script + working-directory: script + run: pnpm start + env: + CAIDO_PAT: ${{ secrets.CAIDO_PAT }} + CAIDO_INSTANCE_URL: http://localhost:8080 +``` + +## Part 6: Customizing for Your Use Case + +You can extend this setup for various security testing scenarios: + +### Create an OOB link + +```typescript +// Execute a workflow +const pluginPackage = await client.plugin.pluginPackage("quickssrf"); +if (pluginPackage === undefined) { + console.error("❌ Error: Plugin package not found"); + process.exit(1); +} + +const settings = await pluginPackage.callFunction({ + name: "getSettings", +}); + +await pluginPackage.callFunction({ + name: "startInteractsh", + arguments: [ + { + serverURL: settings.serverURL, + token: settings.token, + pollingInterval: settings.pollingInterval, + correlationIdLength: settings.correlationIdLength, + correlationIdNonceLength: settings.correlationIdNonceLength, + }, + ], +}); + +const result = await pluginPackage.callFunction({ + name: "generateInteractshUrl", + arguments: [settings.serverURL], +}); +``` + +### Running Scans + +::: info +Will be added soon +::: + +## Next Steps + +For a complete working example, check out the [caido-community/cicd-example](https://github.com/caido-community/cicd-example) repository. diff --git a/src/app/tutorials/headless_orchestration.md b/src/app/tutorials/headless_orchestration.md new file mode 100644 index 0000000..0f9a7c1 --- /dev/null +++ b/src/app/tutorials/headless_orchestration.md @@ -0,0 +1,349 @@ +--- +description: "Learn how to orchestrate headless Caido instances and automate instance configuration via scripting" +--- + +# Orchestrating Caido Headless + +The goal of this tutorial is to automate an headless Caido instances through scripting to ensure it is safely registred and configured without human intervention. This allows many usecases like: + +- **Red boxes**: Pre-configure isolated instances for triaging/pentest/etc +- **CI/CD testing**: Automatically set up instances to run particular tests on-demand +- **AI agent interfaces**: Provide human-in-the-loop interfaces to AI agents + +## Part 1: Creating a Registration Key and Launching the Instance + + +This is feature is available starting with Caido v0.55.3 for Teams. + + +To safely deploy Caido instances without human intervention, you'll need to use a [Registration Key](/dashboard/concepts/registration_key). Registration keys automatically claim new instances, ensuring they're secure even when deployed in automated environments. + +If you are not on a Team plan, you will need to do this registration step manually. + +### Creating a Registration Key + +First, create a registration key in the [Caido Dashboard](https://dashboard.caido.io): + +1. Navigate to your Team workspace +2. Go to the Registration Keys section +3. Click `Create Key` +4. Configure the key: + - **Description**: `Headless Tutorial` + - **Prefix**: `headless` + - **Expiration**: Set an expiration date + - **Reusable**: Yes + +For detailed instructions, see our guide on [creating a registration key](/dashboard/guides/create_registration_key). + +### Downloading the Caido CLI + +To download the latest [Caido CLI](/app/concepts/cli_vs_desktop) version automatically, you can use our [release API](/app/reference/download_links). + +```bash +curl -s https://caido.download/releases/latest +``` + +You can filter with JQ for your specific platform (here `Linux x86_64`): + +```bash +curl -s https://caido.download/releases/latest | jq -r '.links[] | select(.os=="linux" and .arch=="x86_64" and .kind=="cli") | .link' +``` + +::: info +The binary is always packaged in an archive (zip or tar.gz), make sure to unarchive it before the next step! +::: + +### Launching the Instance with a Registration Key + +Once you have a registration key and the binary, launch your Caido instance. You can pass the registration key in two ways: + +**Option 1: Using the `--registration-key` flag:** + +```bash +caido --registration-key ckey_xxxxx +``` + +**Option 2: Using the `CAIDO_REGISTRATION_KEY` environment variable:** + +```bash +export CAIDO_REGISTRATION_KEY=ckey_xxxxx +caido +``` + +When the instance starts, it will automatically register itself and be automatically claimed by the Team. This ensures the instance is secure. + +::: info +For more information about the registration process, see our documentation on [instance registration](/app/concepts/instance_registration). +::: + +::: warning +If you want to expose the instance to the internet, make sure to read our [tutorial](./instance_internet.md) on the subject to do so securely. +::: + +## Part 2: Creating a PAT and Setting Environment Variable + +To authenticate your scripts with the Caido instance, you'll need a [Personal Access Token (PAT)](/dashboard/concepts/pat). PATs allow headless authentication without requiring browser interaction. + +### Creating a PAT + +1. Visit the [Caido Dashboard](https://dashboard.caido.io) +2. Navigate to the Developer page **in your Workspace** +3. Click `+ Create Token` +4. Configure the token: + - **Name**: `Headless automation` + - **Resource Owner**: Select your Team + - **Expiration**: Set an expiration date + +For detailed instructions, see our guide on [creating a PAT](/dashboard/guides/create_pat). + +### Setting the Environment Variable + +Once you have your PAT, set it as an environment variable: + +```bash +export CAIDO_PAT=caido_xxxxx +``` + +You can also set the Caido instance URL (if different from the default): + +```bash +export CAIDO_INSTANCE_URL=http://abc.remote.cai.do:9000 +``` + +::: info +For more information about authentication, see our documentation on [instance authentication](/app/concepts/instance_authentication). +::: + +## Part 3: Creating the Configuration Script + +Now we'll create a script that uses the `@caido/sdk-client` to automatically configure your Caido instance. This script will: + +1. Create and select a project +2. Create a scope preset +3. Create a filter preset +4. Create an environment with environment variables +5. Upload a hosted file (wordlist) + +### Setting Up the Project + +First, create a new directory for your script and initialize it: + +```bash +mkdir caido-automation +cd caido-automation +pnpm init +``` + +Install the Caido SDK client: + +```bash +pnpm install @caido/sdk-client +``` + +::: info +Not all versions of the sdk-client are compatible with the targeted Caido instances. +If you see errors, make sure update your sdk-client version. +::: + +### The Configuration Script + +Create a file named `configure.ts`: + +```typescript +import { Client } from "@caido/sdk-client"; + +async function main() { + // Get the Caido instance URL from environment or use default + const instanceUrl = + process.env["CAIDO_INSTANCE_URL"] ?? "http://localhost:8082"; + + // Get the Personal Access Token from environment + const pat = process.env["CAIDO_PAT"]; + if (pat === undefined || pat === "") { + console.error("❌ Error: CAIDO_PAT environment variable is required"); + console.error(" Set it with: export CAIDO_PAT=caido_xxxxx"); + process.exit(1); + } + + const client = new Client({ + url: instanceUrl, + auth: { + pat: pat, + cache: { + file: ".secrets.json", // This caches the access token on disk to speed up other scripts, can be removed + }, + }, + }); + + await client.connect(); + console.log("✅ Connected to Caido instance"); + + // Verify authentication + const viewer = await client.user.viewer(); + console.log( + `✅ Authenticated as: ${ + viewer.kind === "CloudUser" ? viewer.profile.identity.email : viewer.id + }`, + ); + + // 1. Create and select a project + console.log("\n📁 Creating project..."); + const project = await client.project.create({ + name: "Automated Pentest Environment", + temporary: false, + }); + console.log(`✅ Created project: ${project.name} (${project.id})`); + + await client.project.select(project.id); + console.log(`✅ Selected project: ${project.name}`); + + // 2. Create a scope preset + console.log("\n🎯 Creating scope preset..."); + const scope = await client.scope.create({ + name: "Main Scope", + allowlist: ["*.example.com", "*.test.example.com"], + denylist: ["*.admin.example.com"], + }); + console.log(`✅ Created scope: ${scope.name} (${scope.id})`); + console.log(` In-scope: ${scope.allowlist.join(", ")}`); + console.log(` Out-of-scope: ${scope.denylist.join(", ")}`); + + // 3. Create a filter preset + console.log("\n🔍 Creating filter preset..."); + const filter = await client.filter.create({ + name: "API Requests Only", + alias: "api_only", + clause: 'req.method.eq:"GET" or req.method.eq:"POST"', + }); + console.log(`✅ Created filter preset: ${filter.name} (${filter.alias})`); + + // 4. Create an environment with environment variables + console.log("\n🌍 Creating environment..."); + const environment = await client.environment.create({ + name: "Production Environment", + variables: [ + { + name: "API_BASE_URL", + value: "https://api.example.com", + kind: "PLAIN", + }, + { + name: "API_KEY", + value: "secret-api-key-12345", + kind: "SECRET", + }, + ], + }); + console.log( + `✅ Created environment: ${environment.name} (${environment.id})`, + ); + console.log( + ` Variables: ${environment.variables.map((v) => v.name).join(", ")}`, + ); + + // Add more variables to the environment + await environment.addVariable({ + name: "SESSION_TOKEN", + value: "initial-token-value", + kind: "PLAIN", + }); + console.log(`✅ Added variable: SESSION_TOKEN`); + + // Select the environment + await client.environment.select(environment.id); + console.log(`✅ Selected environment: ${environment.name}`); + + // 5. Upload a hosted file (wordlist) + console.log("\n📄 Uploading hosted file..."); + + // Create a sample wordlist file + // In Node.js 18+, File is available globally + // For older versions, you can use: import { File } from "node-fetch" or similar + const wordlistContent = `admin +administrator +api +backup +config +database +dev +login +password +test +user +`; + + // Create a File object from the content + // Note: File API is available in Node.js 18+; for older versions, use a polyfill + const wordlistFile = new File([wordlistContent], "common-wordlist.txt", { + type: "text/plain", + }); + + // Alternatively, read from an existing file (uncomment readFileSync import above): + // const fileBuffer = readFileSync("path/to/wordlist.txt"); + // const wordlistFile = new File([fileBuffer], "wordlist.txt", { type: "text/plain" }); + + const hostedFile = await client.hostedFile.upload({ + name: "Common Wordlist", + file: wordlistFile, + }); + console.log(`✅ Uploaded hosted file: ${hostedFile.name} (${hostedFile.id})`); + console.log(` Size: ${hostedFile.size} bytes`); + console.log(` Status: ${hostedFile.status}`); + + console.log("\n✨ Configuration complete!"); + console.log(`\nProject ID: ${project.id}`); + console.log(`Scope ID: ${scope.id}`); + console.log(`Filter ID: ${filter.id}`); + console.log(`Environment ID: ${environment.id}`); + console.log(`Hosted File ID: ${hostedFile.id}`); +} + +main().catch((error: unknown) => { + console.error("❌ Fatal error:", error); + process.exit(1); +}); +``` + +### Running the Script + +Make sure your environment variables are set. + +Add the following start command to your `package.json`: + +```json +"scripts": { + "start": "node configure.ts" +} +``` + +Then simply run: + +```bash +pnpm start +``` + +::: info +Modern versions of Node.js can now run TypeScript directly. No compilation step is needed! + +If you see some errors, make sure your Node.js version is up to date. +::: + +### Script Breakdown + +The script performs the following operations: + +1. **Project Creation**: Creates a new project named "Automated Pentest Environment" and selects it as the active project. Projects are containers for all your testing data. + +2. **Scope Preset Creation**: Creates a scope preset that defines which targets are in-scope and out-of-scope. For more details, see our guide on [defining a scope](/app/guides/scopes_defining). + +3. **Filter Preset Creation**: Creates a filter preset using HTTPQL to filter traffic. For more information, see our guide on [defining a filter](/app/guides/filters_defining) and the [HTTPQL reference](/app/reference/httpql). + +4. **Environment Creation**: Creates a custom environment with environment variables. Environment variables can be used in requests and workflows. The script creates both plain and secret variables. For more details, see our guide on [creating environment variables](/app/guides/environment_variables). + +5. **Hosted File Upload**: Uploads a wordlist file that can be used in Automate sessions for systematic payload testing. For more information, see our guides on [uploading files](/app/guides/files_uploading) and [using wordlists in Automate](/app/guides/automate_wordlists). + +## Next Steps + +Your instance is now configured, you can start using it directly as an operator or via further scripting. + +You can also check out our tutorial on [Github Actions](./github_action.md). diff --git a/src/dashboard/concepts/registration_key.md b/src/dashboard/concepts/registration_key.md index 160faf8..fa89b3f 100644 --- a/src/dashboard/concepts/registration_key.md +++ b/src/dashboard/concepts/registration_key.md @@ -1,7 +1,7 @@ # Registration Key -This is feature is available starting with Caido v0.56.0 for Teams. +This is feature is available starting with Caido v0.55.3 for Teams. Registration Keys allow you to automatically claim new instances. This allows you to deploy instances safely without human intervention. For example, ahead of an engagement or on demand in CICD.