> ## Documentation Index
> Fetch the complete documentation index at: https://www.osohq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD with Oso Cloud

> Automate authorization testing and deployment in your CI/CD pipeline.

## GitHub Actions Example

Get started with this complete workflow:

```yaml theme={null}
name: Oso Cloud CI/CD

on: [push, pull_request]

jobs:
  validate-and-test:
    runs-on: ubuntu-latest
    env:
      OSO_URL: "http://localhost:8080"
      OSO_AUTH: "e_0123456789_12345_osotesttoken01xiIn"
    steps:
      - uses: actions/checkout@v4
      - name: Install Oso Cloud CLI
        run: curl -L https://cloud.osohq.com/install.sh | bash
      - name: Validate policy syntax
        run: oso-cloud validate policy/*.polar
      - name: Test policies
        run: oso-cloud test policy/*.polar
      
  deploy:
    if: github.ref == 'refs/heads/main'
    needs: validate-and-test
    runs-on: ubuntu-latest
    env:
      OSO_AUTH: ${{ secrets.OSO_CLOUD_PRODUCTION_KEY }}
    steps:
      - uses: actions/checkout@v4
      - name: Install Oso Cloud CLI
        run: curl -L https://cloud.osohq.com/install.sh | bash
      - name: Deploy to production
        run: oso-cloud policy policy/*.polar
```

* Change `policy/*.polar` to your file paths.
* Add your production API key as `OSO_CLOUD_PRODUCTION_KEY` in GitHub Secrets.

## Local Development Integration

Catch policy errors before they reach your CI pipeline with pre-commit validation.

### Set Up Pre-Commit Hook

Validate Polar syntax before committing:

```bash theme={null}
#!/bin/sh
# Save this to .git/hooks/pre-commit

# Change this to the paths to your polar files
declare -a POLAR_FILES=(
  "policy/authorization.polar"
  "policy/authorization2.polar"
)

POLAR_FILES_CHANGED=false

# Check if any polar files changed in this commit
for POLAR_FILE in "${POLAR_FILES[@]}" ; do
  if git --no-pager diff --cached --name-status | grep -v "^D" | grep "${POLAR_FILE}" >> /dev/null ; then
    POLAR_FILES_CHANGED=true
    break
  fi
done

# Validate syntax if any Polar file changed
! $POLAR_FILES_CHANGED || oso-cloud validate "${POLAR_FILES[@]}"
```

**Make the hook executable:**

```bash theme={null}
chmod 0755 .git/hooks/pre-commit
```

## Pipeline Steps

1. **Validate syntax** - `oso-cloud validate`
2. **Run policy unit tests** - `oso-cloud test`
3. **Run integration tests** with updated policies
4. **Deploy** to target environment

### Testing Configurations

Run fast validation and unit tests on every push to catch errors early.

#### Syntax Validation

Ensure your Polar policies are syntactically correct:

```yaml theme={null}
validate-syntax:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - name: Install Oso Cloud CLI
      run: curl -L https://cloud.osohq.com/install.sh | bash
    - name: Validate policy syntax
      run: oso-cloud validate policy/*.polar
```

**For multiple policy files:** Pass all files in one command - the CLI validates consistency across files.

#### Unit Testing

Run policy tests to verify authorization logic works correctly.

**With Oso Dev Server (Recommended):**

```yaml theme={null}
test-with-dev-server:
  runs-on: ubuntu-latest
  env:
    OSO_URL: "http://localhost:8080"
    OSO_AUTH: "e_0123456789_12345_osotesttoken01xiIn"
  steps:
    - uses: actions/checkout@v4
    - name: Install Oso Cloud CLI
      run: curl -L https://cloud.osohq.com/install.sh | bash
    - name: Install Oso Dev Server
      run: |
        curl https://oso-local-development-binary.s3.amazonaws.com/latest/oso-local-development-binary-linux-x86_64.tar.gz -o oso-dev-server.tar.gz
        tar -xzf oso-dev-server.tar.gz && chmod +x standalone
    - name: Start Dev Server
      run: ./standalone &
    - name: Run policy tests
      run: oso-cloud test policy/*.polar
```

**With Oso Cloud:**

```yaml theme={null}
test-on-oso-cloud:
  runs-on: ubuntu-latest
  env:
    OSO_AUTH: ${{ secrets.OSO_CLOUD_READ_ONLY_KEY }}
  steps:
    - uses: actions/checkout@v4
    - name: Install Oso Cloud CLI
      run: curl -L https://cloud.osohq.com/install.sh | bash
    - name: Run policy tests
      run: oso-cloud test policy/*.polar
```

<Note>
  Dev Server removes external dependencies for faster CI runs.
</Note>

## Application Testing

Run integration tests to ensure your application works correctly with updated authorization policies.

### Shared Test Environment

```yaml theme={null}
deploy-to-test:
  runs-on: ubuntu-latest
  env:
    OSO_AUTH: ${{ secrets.OSO_CLOUD_TEST_KEY }}
  steps:
    - uses: actions/checkout@v4
    - name: Install Oso Cloud CLI
      run: curl -L https://cloud.osohq.com/install.sh | bash
    - name: Deploy to test environment
      run: oso-cloud policy policy/*.polar
    - name: Run application tests
      run: npm test # or your test command
```

<Warning>
  Queue PR jobs to avoid policy conflicts.
</Warning>

### Isolated Environments (Dev Server)

```yaml theme={null}
test-with-isolation:
  runs-on: ubuntu-latest
  env:
    OSO_URL: "http://localhost:8080"
  steps:
    - uses: actions/checkout@v4
    - name: Install tools
      run: |
        curl -L https://cloud.osohq.com/install.sh | bash
        curl https://oso-local-development-binary.s3.amazonaws.com/latest/oso-local-development-binary-linux-x86_64.tar.gz -o oso-dev-server.tar.gz
        tar -xzf oso-dev-server.tar.gz && chmod +x standalone
    - name: Start Dev Server
      run: ./standalone &
    - name: Create test environment
      run: echo "OSO_AUTH=$(curl -s -X POST http://localhost:8080/test_environment?copy=false | jq -r '.token')" >> "$GITHUB_ENV"
    - name: Deploy policy
      run: oso-cloud policy policy/*.polar
    - name: Run application tests
      run: npm test
```

## Production Deployment

Deploy validated policies to production safely.

```yaml theme={null}
deploy-production:
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  needs: [validate-and-test, application-tests]
  runs-on: ubuntu-latest
  env:
    OSO_AUTH: ${{ secrets.OSO_CLOUD_PRODUCTION_KEY }}
  steps:
    - uses: actions/checkout@v4
    - name: Install Oso Cloud CLI
      run: curl -L https://cloud.osohq.com/install.sh | bash
    - name: Deploy to production
      run: oso-cloud policy policy/*.polar
```

**Best practices:**

* Use separate API keys for test and production
* Store keys as encrypted secrets, never in plaintext
* Use read-only keys for tests, read-write for deploys

## Advanced Configuration

<AccordionGroup>
  <Accordion title="Version pinning">
    Pin specific tool versions for consistent CI/CD environments:

    **Oso Cloud CLI:**

    ```bash theme={null}
    curl -L https://cloud.osohq.com/install.sh | OSO_CLI_VERSION="x.y.z" bash
    ```

    **Oso Dev Server:**

    ```bash theme={null}
    curl https://oso-local-development-binary.s3.amazonaws.com/x.y.z/oso-local-development-binary-linux-x86_64.tar.gz -o oso-dev-server.tar.gz
    ```

    Replace "x.y.z" with your desired version.
  </Accordion>

  <Accordion title="Docker-based Dev Server">
    Deploy the Oso Dev Server as a container for isolated test environments:

    ```bash theme={null}
    # Run the Dev Server with policy files mounted from the host 
    # and automatically reload on policy changes
    docker run --rm -p 8080:8080 \
      --mount type=bind,src="$(pwd)/policy",dst=/policies \
      public.ecr.aws/osohq/dev-server:latest \
      --watch-for-changes /policies/policy.polar
    ```
  </Accordion>

  <Accordion title="Local Authorization Validation">
    Validate Local Authorization configuration against your database schema:

    ```yaml theme={null}
    validate-local-auth:
      runs-on: ubuntu-latest
      services:
        postgres:
          image: postgres:13
          env:
            POSTGRES_PASSWORD: password
          options: >-
            --health-cmd pg_isready
            --health-interval 10s
            --health-timeout 5s
            --health-retries 5

      steps:
        - uses: actions/checkout@v4
        - name: Install Oso Cloud CLI
          run: curl -L https://cloud.osohq.com/install.sh | bash
        - name: Validate Local Authorization config
          run: |
            oso-cloud validate-local-authorization-config \
              ./local_authorization_config.yaml \
              -c postgres://postgres:password@localhost:5432/postgres \
              -p policy/*.polar
    ```

    **Requirements:** Database access needed to validate queries against current schema.
  </Accordion>

  <Accordion title="Managing Facts in CI">
    Best practices for handling authorization data in CI/CD:

    **Seed Essential Data:**

    ```yaml theme={null}
    seed-facts:
      runs-on: ubuntu-latest
      env:
        OSO_AUTH: ${{ secrets.OSO_CLOUD_TEST_KEY }}
      steps:
        - uses: actions/checkout@v4
        - name: Install Oso Cloud CLI
          run: curl -L https://cloud.osohq.com/install.sh | bash
        - name: Seed test environment
          run: ./scripts/seed-oso-facts.sh
    ```

    **Recommendations:**

    * Let applications generate facts naturally during tests
    * Only seed data that's required on startup (roles, permissions)
    * Keep fact seeding scripts in sync with database seeding
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Installation Issues">
    **CLI installation fails:**

    * Check internet connectivity and firewall settings
    * Verify curl is installed: `curl --version`

    **Dev Server won't start:**

    * Check port 8080 availability: `lsof -i :8080`
    * Verify binary permissions: `chmod +x standalone`
    * Review startup logs for detailed errors
  </Accordion>

  <Accordion title="Authentication Problems">
    **"Authentication failed" errors:**

    * Verify API key is set correctly in environment
    * Check key has appropriate permissions (read-only vs read-write)
    * Ensure no extra whitespace in secret values

    **Wrong environment targeted:**

    * Confirm OSO\_URL points to correct environment
    * Check OSO\_AUTH matches the target environment's key
    * Verify environment variables are properly scoped to jobs
  </Accordion>

  <Accordion title="Policy and Test Failures">
    **Syntax validation fails:**

    * Check policy files for syntax errors locally first
    * Ensure all referenced policy files are included
    * Verify file paths are correct in CI configuration

    **Tests fail in CI but pass locally:**

    * Check environment variable differences
    * Verify Dev Server is fully started before running tests
    * Ensure test data is properly seeded

    **Deployment fails:**

    * Check production API key permissions
    * Verify policy syntax before deployment
    * Review Oso Cloud environment status
  </Accordion>
</AccordionGroup>

## Next Steps

1. [**Set up local development tools**](/develop/local-dev/env-setup) for policy authoring
2. [**Write comprehensive policies**](/develop/policies/overview) using Polar
3. [**Implement authorization checks**](/develop/enforce/authorize-requests) in your application
4. [**Monitor and debug**](/develop/troubleshooting/logs) authorization in production

***

Need help setting up your CI/CD pipeline? [Schedule a call with an Oso engineer](https://osohq.com/meet-oso) - we're happy to help.
