We are trying to set up a CI/CD pipeline for our CXone infrastructure using the Nice CXone Terraform provider. The goal is simple: run terraform plan on every pull request to validate changes, and run terraform apply only when the PR is merged into the main branch. We are using GitHub Actions and authenticating via OIDC to avoid storing long-lived credentials.
The issue is that the plan step fails with a 403 Forbidden error when the workflow runs on a pull request event. It works fine on push events to main. Here is the relevant part of our workflow file:
name: Terraform Plan
on:
pull_request:
branches: [main]
jobs:
plan:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Authenticate to CXone
run: |
echo "Fetching OIDC token..."
curl -s -X POST https://{{ORG_ID}}.my.cxone.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token_type=urn:ietf:params:oauth:token-type:id-token&subject_token=$(oidc-token)&requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
| jq -r '.access_token' > /tmp/access_token
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan -var-file="env.tfvars" -out=tfplan
The OIDC token exchange seems to work, as we get a token back. But when Terraform tries to read the current state or plan, the API rejects it.
What I have tried:
- Verified the OIDC provider configuration in CXone Admin. The audience claim matches.
- Checked the token in jwt.io. The claims look correct.
- Tried passing the token directly as an environment variable
CXONE_TOKENinstead of exchanging it. Same 403. - Confirmed the client ID has the right scope for
admin:organization.
Is there a specific permission or claim required for PR events that differs from push events? Or is the token exchange flow different for temporary workflows? The error message from the API is just Forbidden. No extra details in the response body.