Skip to content

docs: clarify token privilege scoping#1101

Open
Aamod007 wants to merge 3 commits into
layer5io:masterfrom
Aamod007:docs-token-privilege-scoping
Open

docs: clarify token privilege scoping#1101
Aamod007 wants to merge 3 commits into
layer5io:masterfrom
Aamod007:docs-token-privilege-scoping

Conversation

@Aamod007

@Aamod007 Aamod007 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Description

This PR resolves Issue #378 by explicitly clarifying how API authentication tokens handle privileges in Layer5.

Changes Made

  • Added a new \Privilege Scoping\ section to \content/en/cloud/concepts/identity-and-security/tokens.md.
  • Clarified that tokens are identity-scoped, meaning they inherently carry the exact same privileges, roles, and permissions as the user account that generated them.
  • Specified that fine-grained, token-specific privilege scopes (like strictly read-only tokens) are not currently supported, ensuring users understand that the token grants the bearer the same level of access as the generating user across all environments.

ScreenShot

Screenshot 2026-06-14 164640

Closes #378

Summary by CodeRabbit

  • Documentation
    • Added a “Privilege Scoping” subsection to the tokens guide explaining that API tokens are identity-scoped and inherit the same privileges, roles, and permissions as the associated user.
    • Clarified that fine-grained, token-specific privilege scopes (e.g., read-only tokens) are not currently supported.
  • Chores
    • Introduced a dedicated preview build workflow for pull requests and switched previews to an artifact-based flow.
    • Updated preview deployment and cleanup behavior to reliably target the correct pull request and trigger on the appropriate events.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds a new 'Privilege Scoping' section to the Layer5 Cloud tokens documentation to clarify that API tokens are identity-scoped. The review feedback suggests updating this new section to use the second-person perspective ('you', 'your') to maintain consistency with the rest of the document, and provides a code suggestion to resolve this.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread content/en/cloud/concepts/identity-and-security/tokens.md Outdated
@Aamod007
Aamod007 force-pushed the docs-token-privilege-scoping branch from 965cc21 to ce55e68 Compare June 14, 2026 11:14
@Aamod007

Aamod007 commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

@leecalcote @sudhanshutech @Bhumikagarggg , could you please take a look and review it when you have a chance?

@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview deployment: https://docs.layer5.io/pr-preview/pr-1101/

Note: Preview may take a moment (GitHub Pages deployment in progress). Please wait and refresh. Track deployment here

@Aamod007
Aamod007 force-pushed the docs-token-privilege-scoping branch from 0fc9826 to 47e95f8 Compare June 17, 2026 12:29
@Aamod007
Aamod007 force-pushed the docs-token-privilege-scoping branch 2 times, most recently from b410a1d to 9f4a651 Compare July 21, 2026 12:55
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds an artifact-producing workflow for pull request previews, updates deployment and cleanup to consume those artifacts, and documents that API tokens inherit account privileges without fine-grained token-specific scopes.

Changes

Artifact-based PR preview pipeline

Layer / File(s) Summary
PR preview artifact build
.github/workflows/build-pr-preview.yml
Builds previews with pinned tooling, preview environment variables, crawler blocking, PR metadata, and one-day artifact retention.
Preview artifact deployment and cleanup
.github/workflows/build-and-preview-docs.yml
Deploys completed preview artifacts, updates event-based retention and comments, and removes previews when pull requests close.

Token privilege documentation

Layer / File(s) Summary
Privilege scoping guidance
content/en/cloud/concepts/identity-and-security/tokens.md
Documents identity-scoped API token privileges and the lack of fine-grained token-specific scopes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant BuildPRPreview
  participant ArtifactStorage
  participant PreviewDeployment
  participant GhPages
  PullRequest->>BuildPRPreview: trigger preview build
  BuildPRPreview->>ArtifactStorage: upload public/ artifact
  ArtifactStorage->>PreviewDeployment: provide completed preview artifact
  PreviewDeployment->>GhPages: deploy preview
  PreviewDeployment->>PullRequest: comment preview URL
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main docs change about token privilege scoping.
Linked Issues check ✅ Passed The docs addition answers issue #378 by stating tokens are identity-scoped and do not support token-specific scopes.
Out of Scope Changes check ✅ Passed The workflow changes match the stated PR objective to separate preview builds from privileged deployment, so nothing appears unrelated.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@content/en/cloud/concepts/identity-and-security/tokens.md`:
- Around line 27-29: Update the API token privilege description in the
identity-and-security tokens documentation to state that tokens inherit the
requesting user’s roles and permissions within the organization and environment
selected by the request context. Clarify that users may have different access
levels across organizations and that a token does not grant uniform access to
every organization, while preserving the existing explanation that
token-specific privilege scopes are unsupported.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c5188968-5f6c-4d91-a6a4-97ee686dc09e

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8ae65 and 9f4a651.

📒 Files selected for processing (1)
  • content/en/cloud/concepts/identity-and-security/tokens.md

Comment thread content/en/cloud/concepts/identity-and-security/tokens.md Outdated
@Aamod007

Copy link
Copy Markdown
Contributor Author

@coderabbitai I have updated the documentation to clarify that the token inherits privileges for the specified organization and environment. Also, fixed the actions/checkout 'pull_request_target' security error by setting 'allow-unsafe-pr-checkout: true'.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Changed files ---'
git diff --name-status HEAD^ HEAD

printf '%s\n' '--- Tokens documentation diff ---'
git diff HEAD^ HEAD -- content/en/cloud/concepts/identity-and-security/tokens.md 2>/dev/null || true

printf '%s\n' '--- Token documentation context ---'
if [ -f content/en/cloud/concepts/identity-and-security/tokens.md ]; then
  nl -ba content/en/cloud/concepts/identity-and-security/tokens.md | sed -n '1,240p'
fi

printf '%s\n' '--- pull_request_target and checkout configuration ---'
rg -n -C 6 --glob '*.yml' --glob '*.yaml' \
  'pull_request_target|actions/checkout|allow-unsafe-pr-checkout' .github 2>/dev/null || true

printf '%s\n' '--- Workflow-file diffs ---'
git diff --name-only HEAD^ HEAD | grep -E '^\.github/.*\.(yml|yaml)$' | while IFS= read -r workflow; do
  printf '\n--- %s ---\n' "$workflow"
  git diff HEAD^ HEAD -- "$workflow"
done

Length of output: 2913


🏁 Script executed:

#!/bin/bash
set -u

workflow=".github/workflows/build-and-preview-docs.yml"

echo '--- Workflow diff ---'
git diff HEAD^ HEAD -- "$workflow" || true

echo '--- Current workflow (numbered with awk) ---'
if [ -f "$workflow" ]; then
  awk '{printf "%5d  %s\n", NR, $0}' "$workflow"
else
  echo "Workflow not found: $workflow"
fi

echo '--- Relevant workflow constructs across GitHub Actions files ---'
find .github -type f \( -name '*.yml' -o -name '*.yaml' \) -print 2>/dev/null | while IFS= read -r file; do
  awk -v file="$file" '
    /pull_request_target|actions\/checkout|allow-unsafe-pr-checkout|^[[:space:]]*permissions:|^[[:space:]]*run:|uses:/ {
      printf "%s:%d: %s\n", file, NR, $0
    }
  ' "$file"
done

Length of output: 15806


The Comment image shows the Layer5 Docs Tokens page. Its banner reads “API Tokens are User-Scoped. Not Organization-Scoped”; the visible “Privilege Scoping” text says a token carries the user’s privileges across all environments and organizations they belong to. It also includes the Tokens navigation item, the page table of contents, and an Authorization: token example.

@Aamod007, the documentation update looks correct: it now clearly states that permissions are evaluated for the organization and environment selected by the request context, and that roles may vary across organizations.

However, allow-unsafe-pr-checkout: true is not a safe resolution for the checkout error. This workflow uses pull_request_target with contents: write and pull-requests: write, checks out untrusted fork PR code, then executes npm ci and npm run build:preview. Enabling unsafe checkout allows a malicious fork to run arbitrary package scripts with that write-capable token, potentially modifying repository content or posting/editing PR comments.

Please keep privileged pull_request_target workflows from checking out or executing fork PR code. Split the preview build into an unprivileged pull_request workflow, and reserve any privileged deployment/commenting step for trusted artifacts or base-repository PRs only.


✏️ Learnings added
Learnt from: Aamod007
URL: https://github.com/layer5io/docs/pull/1101

Timestamp: 2026-07-21T17:36:42.838Z
Learning: In `content/en/cloud/concepts/identity-and-security/tokens.md`, Layer5 Cloud API tokens are identity-scoped: effective privileges are evaluated using the organization and environment selected in the request context. Users can have different roles and permissions in different organizations; Layer5 does not support fine-grained, token-specific privilege scopes.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build-and-preview-docs.yml:
- Line 39: Update the workflow job containing allow-unsafe-pr-checkout so
untrusted PR code is never executed by pull_request_target with write-scoped
permissions. Move npm ci and npm run build:preview into an unprivileged
pull_request job, or separate privileged deployment and cleanup steps from the
PR checkout while preserving the existing deployment behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0883060f-300e-49fc-8a55-e2c14a579946

📥 Commits

Reviewing files that changed from the base of the PR and between 9f4a651 and 94c8a4f.

📒 Files selected for processing (2)
  • .github/workflows/build-and-preview-docs.yml
  • content/en/cloud/concepts/identity-and-security/tokens.md

Comment thread .github/workflows/build-and-preview-docs.yml Outdated
@Aamod007
Aamod007 force-pushed the docs-token-privilege-scoping branch from 94c8a4f to 312851b Compare July 21, 2026 17:41
@Aamod007

Copy link
Copy Markdown
Contributor Author

@coderabbitai Resolved! The PR preview workflow has been refactored to separate the unprivileged build step ('build-pr-preview.yml' on 'pull_request') from the privileged deployment workflow ('build-and-preview-docs.yml' on 'workflow_run'). No untrusted code is executed with write-scoped permissions, and 'allow-unsafe-pr-checkout' has been removed.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

The Comment image shows the Layer5 Docs Tokens page in a dark theme. It includes the banner “API Tokens are User-Scoped. Not Organization-Scoped” and a “Privilege Scoping” section stating that tokens inherit the user account’s privileges, roles, and permissions, without fine-grained token-specific scopes. The page also shows the Tokens sidebar item, table of contents, and an Authorization: bearer-token example.

@Aamod007, thanks for resolving this. Separating the unprivileged PR build from the privileged workflow_run deployment flow, while removing allow-unsafe-pr-checkout, addresses the risk of executing untrusted fork code with write-scoped credentials.

🐇 ✅

Aamod007 added 2 commits July 21, 2026 23:12
Signed-off-by: Aamod007 <aamodkumar2006@gmail.com>
Signed-off-by: Aamod007 <aamodkumar2006@gmail.com>
@Aamod007
Aamod007 force-pushed the docs-token-privilege-scoping branch from 312851b to 5e671ae Compare July 21, 2026 17:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
.github/workflows/build-pr-preview.yml (4)

37-45: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Sass is installed before Node is pinned to v20.

"Install Dart Sass (npm)" runs npm i -g sass before "Setup Node" configures Node 20 and updates PATH. This means the global sass install uses whichever Node/npm ships on the runner image by default, not the pinned version, and the resulting global bin may not even be resolvable once setup-node adjusts PATH. Reorder so Node is set up first for a consistent, reproducible toolchain.

♻️ Suggested reorder
-      - name: Install Dart Sass (npm)
-        run: |
-          npm i -g sass
-          sass --version
-
       - name: Setup Node
         uses: actions/setup-node@v4
         with:
           node-version: '20'
+
+      - name: Install Dart Sass (npm)
+        run: |
+          npm i -g sass
+          sass --version
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-pr-preview.yml around lines 37 - 45, Move the “Setup
Node” step using actions/setup-node@v4 before the “Install Dart Sass (npm)”
step, so npm i -g sass and sass --version run under the pinned Node 20
toolchain.

37-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the Sass version.

npm i -g sass installs the latest version with no pin or lockfile, so builds aren't reproducible and can break silently on a new Sass release, as flagged by zizmor's ad-hoc-packages check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-pr-preview.yml around lines 37 - 40, Update the
“Install Dart Sass (npm)” workflow step to install an explicitly pinned Sass
version instead of using the unversioned package specifier, while preserving the
existing sass --version verification.

Source: Linters/SAST tools


26-30: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Persist-credentials not disabled before running untrusted PR build tooling.

This job checks out PR head content and then runs untrusted-controlled build steps (npm install/build, Hugo). By default actions/checkout persists the GITHUB_TOKEN credential in .git/config, which any subsequent process (npm postinstall scripts, Hugo, Sass) can read from disk and exfiltrate. Add persist-credentials: false since no git push happens in this job.

🔒️ Suggested fix
       - name: Checkout PR code
         uses: actions/checkout@v6
         with:
           submodules: recursive
           fetch-depth: 0
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-pr-preview.yml around lines 26 - 30, Update the
actions/checkout step in the PR preview workflow to set persist-credentials to
false, while preserving the existing recursive submodule and full-history
checkout options.

Source: Linters/SAST tools


32-35: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

No checksum verification for the downloaded Hugo .deb.

The Hugo release asset is fetched over HTTPS and installed via dpkg -i without verifying a checksum/signature against the GitHub release. Consider verifying sha256sum against Hugo's published checksums file for supply-chain hardening.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-pr-preview.yml around lines 32 - 35, Update the
“Install Hugo CLI” workflow step to download Hugo’s published checksum file,
verify the downloaded .deb with sha256sum against the matching release checksum,
and only run dpkg -i after verification succeeds.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build-and-preview-docs.yml:
- Around line 33-41: Update the “Get PR number” step to read the PR number from
public/PR_NUMBER.txt in the downloaded artifact instead of relying on
github.event.workflow_run.pull_requests[0].number; retain the direct
pull_request event path as appropriate, and ensure the resulting pr_number
output is populated before artifact naming and downstream deploy/comment steps.
- Around line 11-13: Update the workflow-level permissions block to add actions:
read alongside the existing contents and pull-requests permissions, enabling
actions/download-artifact@v4 to access artifacts from another workflow run via
workflow_run.

---

Nitpick comments:
In @.github/workflows/build-pr-preview.yml:
- Around line 37-45: Move the “Setup Node” step using actions/setup-node@v4
before the “Install Dart Sass (npm)” step, so npm i -g sass and sass --version
run under the pinned Node 20 toolchain.
- Around line 37-40: Update the “Install Dart Sass (npm)” workflow step to
install an explicitly pinned Sass version instead of using the unversioned
package specifier, while preserving the existing sass --version verification.
- Around line 26-30: Update the actions/checkout step in the PR preview workflow
to set persist-credentials to false, while preserving the existing recursive
submodule and full-history checkout options.
- Around line 32-35: Update the “Install Hugo CLI” workflow step to download
Hugo’s published checksum file, verify the downloaded .deb with sha256sum
against the matching release checksum, and only run dpkg -i after verification
succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 35e1fba5-376c-4e3b-a345-2df58910cfce

📥 Commits

Reviewing files that changed from the base of the PR and between 94c8a4f and 312851b.

📒 Files selected for processing (3)
  • .github/workflows/build-and-preview-docs.yml
  • .github/workflows/build-pr-preview.yml
  • content/en/cloud/concepts/identity-and-security/tokens.md

Comment thread .github/workflows/build-and-preview-docs.yml
Comment thread .github/workflows/build-and-preview-docs.yml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
.github/workflows/build-pr-preview.yml (1)

37-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make Sass installation reproducible and select Node first.

Line 39 installs the mutable latest Sass release before Line 43 selects Node 20. Set up Node first, then consume a pinned Sass version from the project’s locked dependencies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-pr-preview.yml around lines 37 - 45, Reorder the
workflow so the actions/setup-node step configures Node 20 before Sass
installation. Update the Install Dart Sass (npm) step to install Sass from the
project’s locked dependencies at a reproducible pinned version, rather than
using the mutable global latest package, while preserving the sass --version
verification.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/build-and-preview-docs.yml:
- Around line 26-28: Update the workflow job condition around the existing
trigger checks to resolve the associated pull request and query its current
state before proceeding. Gate artifact download, deployment, retention, and
comment steps on the pull request still being open, so delayed workflow_run
completions cannot redeploy a closed PR preview.

In @.github/workflows/build-pr-preview.yml:
- Around line 26-30: Update the “Checkout PR code” step using
actions/checkout@v6 to disable persisted credentials via its checkout
configuration, while preserving recursive submodules and full fetch history.
- Around line 47-49: Remove the unconditional `|| true` from the “Install
dependencies” workflow step so `npm ci` failures cause the job to fail. Preserve
the conditional lockfile check, but ensure dependency installation errors are
surfaced rather than allowing the workflow to continue with incomplete
dependencies.

---

Nitpick comments:
In @.github/workflows/build-pr-preview.yml:
- Around line 37-45: Reorder the workflow so the actions/setup-node step
configures Node 20 before Sass installation. Update the Install Dart Sass (npm)
step to install Sass from the project’s locked dependencies at a reproducible
pinned version, rather than using the mutable global latest package, while
preserving the sass --version verification.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: daba9cd8-9753-4b73-9f45-f4933db832e1

📥 Commits

Reviewing files that changed from the base of the PR and between 312851b and 5e671ae.

📒 Files selected for processing (3)
  • .github/workflows/build-and-preview-docs.yml
  • .github/workflows/build-pr-preview.yml
  • content/en/cloud/concepts/identity-and-security/tokens.md

Comment on lines +26 to +28
if: >
(github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') ||
(github.event_name == 'pull_request_target' && github.event.action == 'closed')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Do not deploy a preview after its PR has closed.

A build can complete after the close-triggered cleanup finishes; this job will then redeploy the closed PR’s preview and leave it until retention pruning. Resolve the PR first, query its current state, and gate artifact download, deployment, retention, and comments on it still being open.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-and-preview-docs.yml around lines 26 - 28, Update
the workflow job condition around the existing trigger checks to resolve the
associated pull request and query its current state before proceeding. Gate
artifact download, deployment, retention, and comment steps on the pull request
still being open, so delayed workflow_run completions cannot redeploy a closed
PR preview.

Comment thread .github/workflows/build-pr-preview.yml
Comment thread .github/workflows/build-pr-preview.yml Outdated
Signed-off-by: Aamod007 <aamodkumar2006@gmail.com>
@Aamod007

Aamod007 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Thank you for the detailed review! I have addressed all 5 items:

  1. Permissions: Added actions: read to build-and-preview-docs.yml permissions so actions/download-artifact can read run artifacts.
  2. PR Number Resolution: Updated build-and-preview-docs.yml to download the artifact by run ID and resolve the PR number directly from ./public/PR_NUMBER.txt (handling empty pull_requests payloads from fork PRs).
  3. Closed PR Guard: Added a step using actions/github-script to verify the PR state is still open before executing deployment, retention, or comment steps.
  4. Checkout Credentials: Set persist-credentials: false on the checkout step in build-pr-preview.yml.
  5. Strict npm ci: Removed || true from
    pm ci in build-pr-preview.yml to ensure dependency installation failures halt the build.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- Workflow outlines ---'
for workflow in \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml
do
  if [ -f "$workflow" ]; then
    echo "--- $workflow ---"
    nl -ba "$workflow"
  else
    echo "Missing: $workflow"
  fi
done

echo '--- Current PR diff for the two workflows ---'
git diff "$(git merge-base HEAD origin/master 2>/dev/null || git rev-parse HEAD^)" HEAD -- \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml || true

echo '--- Relevant workflow constructs across both files ---'
rg -n -C 4 \
  '^(name|on|permissions|jobs):|workflow_run|pull_request_target|pull_request:|actions/download-artifact|actions/github-script|actions/checkout|persist-credentials|npm ci|PR_NUMBER|pull_requests|if:' \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml

Length of output: 1342


🏁 Script executed:

#!/bin/bash
set -u

for workflow in \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml
do
  echo "--- ${workflow} ---"
  if [ -f "$workflow" ]; then
    sed -n '1,260p' "$workflow"
  else
    echo "Missing workflow"
  fi
done

echo '--- Current PR diff for these workflows ---'
base="$(git merge-base HEAD origin/master 2>/dev/null || git rev-parse HEAD^ 2>/dev/null || true)"
if [ -n "$base" ]; then
  git diff "$base" HEAD -- \
    .github/workflows/build-and-preview-docs.yml \
    .github/workflows/build-pr-preview.yml || true
else
  echo 'Could not determine a diff base.'
fi

echo '--- Security- and behavior-relevant lines ---'
rg -n -C 5 \
  'workflow_run|pull_request_target|pull_request:|permissions:|actions: read|actions/download-artifact|run-id:|github.event.workflow_run.id|PR_NUMBER|pull_requests|actions/github-script|state.*open|persist-credentials|npm ci|allow-unsafe-pr-checkout|if:' \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml 2>/dev/null || true

Length of output: 34875


The Comment image shows the Layer5 Docs Tokens page in dark mode. It includes the callout “API Tokens are User-Scoped. Not Organization-Scoped”, a “Privilege Scoping” section explaining identity-scoped token permissions and the lack of fine-grained token-specific scopes, the left navigation with Tokens selected, an On this page panel, and an Authorization: example.

@Aamod007, verified—each of the five follow-up items is correctly addressed:

  1. .github/workflows/build-and-preview-docs.yml grants actions: read, allowing artifact download.
  2. The deployment workflow downloads the artifact by the triggering workflow run ID and resolves the PR number from public/PR_NUMBER.txt, avoiding reliance on a potentially empty workflow_run.pull_requests payload.
  3. The PR status check gates preview deployment, retention/pruning, and PR-comment steps on the PR still being open.
  4. .github/workflows/build-pr-preview.yml sets persist-credentials: false for the unprivileged PR checkout.
  5. npm ci is no longer allowed to fail silently.

The privileged workflow continues to avoid checking out or executing untrusted PR code, and allow-unsafe-pr-checkout is absent. ✅

🐇✨

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@Aamod007 The Comment image shows the dark-themed Layer5 Docs Tokens page, with the callout “API Tokens are User-Scoped. Not Organization-Scoped”, the “Privilege Scoping” section, Tokens highlighted in the left navigation, the right-side table of contents, and an Authorization: example.

Thanks for the thorough follow-up. The unprivileged artifact build, run-ID-based artifact retrieval and PR-number resolution, open-PR guard, credential-free checkout, and strict npm ci behavior collectively address the identified security and workflow reliability concerns.

🐇 ✅

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

for workflow in \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml
do
  echo "--- ${workflow} ---"
  if [ -f "$workflow" ]; then
    nl -ba "$workflow"
  else
    echo "Missing workflow: $workflow"
  fi
done

echo '--- Relevant workflow configuration ---'
rg -n -C 4 \
  'workflow_run|pull_request_target|pull_request:|permissions:|actions: read|actions/download-artifact|run-id:|github\.event\.workflow_run\.id|PR_NUMBER|pull_requests|actions/github-script|state.*open|persist-credentials|npm ci|allow-unsafe-pr-checkout|if:' \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml || true

echo '--- Diff against merge base ---'
base="$(git merge-base HEAD origin/master 2>/dev/null || git rev-parse HEAD^)"
git diff "$base" HEAD -- \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml || true

Length of output: 1342


🏁 Script executed:

#!/bin/bash
set -eu

for workflow in \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml
do
  echo "--- ${workflow} ---"
  if [ -f "$workflow" ]; then
    awk '{ printf "%5d  %s\n", NR, $0 }' "$workflow"
  else
    echo "Missing workflow: $workflow"
  fi
done

echo '--- Relevant workflow configuration ---'
rg -n -C 4 \
  'workflow_run|pull_request_target|pull_request:|permissions:|actions: read|actions/download-artifact|run-id:|github\.event\.workflow_run\.id|PR_NUMBER|pull_requests|actions/github-script|state.*open|persist-credentials|npm ci|allow-unsafe-pr-checkout|if:' \
  .github/workflows/build-and-preview-docs.yml \
  .github/workflows/build-pr-preview.yml 2>/dev/null || true

echo '--- Diff against merge base ---'
base="$(git merge-base HEAD origin/master 2>/dev/null || git rev-parse HEAD^ 2>/dev/null || true)"
if [ -n "$base" ]; then
  git diff "$base" HEAD -- \
    .github/workflows/build-and-preview-docs.yml \
    .github/workflows/build-pr-preview.yml || true
else
  echo 'Could not determine a merge base.'
fi

Length of output: 35608


The Comment image shows the Layer5 Docs Tokens page in dark mode. It includes the “API Tokens are User-Scoped. Not Organization-Scoped” callout, the “Privilege Scoping” section explaining identity-scoped permissions and the absence of fine-grained token-specific scopes, Tokens selected in the sidebar, the On this page table of contents, and an Authorization: example.

@Aamod007, verified—all five follow-up items are correctly addressed:

  1. .github/workflows/build-and-preview-docs.yml now grants actions: read for artifact access.
  2. The deployment workflow downloads the artifact by the triggering run ID and gets the PR number from public/PR_NUMBER.txt, avoiding reliance on workflow_run.pull_requests.
  3. The PR-status check gates deployment, retention/pruning, and comment steps on the PR still being open.
  4. .github/workflows/build-pr-preview.yml sets persist-credentials: false.
  5. npm ci now fails the build when dependency installation fails.

The privileged workflow does not check out or execute untrusted PR code, and allow-unsafe-pr-checkout remains absent. ✅

🐇✨

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/build-and-preview-docs.yml (1)

16-17: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Concurrency group keyed on workflow_run.id no longer serializes deploys per PR.

github.event.workflow_run.id is unique per triggering run, so every workflow_run-triggered job gets its own singleton concurrency group — this effectively disables concurrency control for the primary trigger path. Rapid successive pushes to the same PR (each producing a separate build → separate workflow_run.id) can now run deploy jobs concurrently, racing on the same gh-pages branch: both the pr-preview-action deploy step and the git commit/push in "Prune old PR previews" (lines 134-138) write to that branch, so overlapping runs can hit push conflicts or non-deterministic preview content.

This may have been chosen to dodge the forked-PR case where pull_requests[0].number is empty (which would otherwise collapse unrelated PRs into the same empty-string group) — but github.event.workflow_run.head_sha is reliably populated even for forked PRs and avoids both problems: it groups reruns of the same commit together without merging unrelated PRs.

♻️ Suggested fix
 concurrency:
-  group: preview-${{ github.event.workflow_run.id || github.event.pull_request.number || github.run_id }}
+  group: preview-${{ github.event.workflow_run.head_sha || github.event.pull_request.number || github.run_id }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/build-and-preview-docs.yml around lines 16 - 17, Update
the concurrency group expression in the workflow to use
github.event.workflow_run.head_sha as the workflow_run-specific key, with the
existing pull_request.number and github.run_id fallbacks preserved for other
trigger types. This must serialize jobs for the same commit while keeping
unrelated forked-PR runs in separate groups.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/build-and-preview-docs.yml:
- Around line 16-17: Update the concurrency group expression in the workflow to
use github.event.workflow_run.head_sha as the workflow_run-specific key, with
the existing pull_request.number and github.run_id fallbacks preserved for other
trigger types. This must serialize jobs for the same commit while keeping
unrelated forked-PR runs in separate groups.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4f1c1ea9-c7db-4ea2-aad9-9100ed3fceef

📥 Commits

Reviewing files that changed from the base of the PR and between 5e671ae and ccacd29.

📒 Files selected for processing (2)
  • .github/workflows/build-and-preview-docs.yml
  • .github/workflows/build-pr-preview.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/build-pr-preview.yml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Docs] Are authentication tokens privilege-scoped?

1 participant