Add PDCP connectivity check to -hc - #7574
Conversation
WalkthroughPDCP API connectivity validation is added to ChangesPDCP health check
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant DoHealthCheck
participant appendPDCPHealthCheck
participant PDCPAuth as PDCP auth handler
participant PDCPServer
DoHealthCheck->>appendPDCPHealthCheck: append PDCP health result
appendPDCPHealthCheck->>PDCPAuth: retrieve credentials
PDCPAuth-->>appendPDCPHealthCheck: credentials or ErrNoCreds
appendPDCPHealthCheck->>PDCPServer: validate API key
PDCPServer-->>appendPDCPHealthCheck: identity or validation error
appendPDCPHealthCheck-->>DoHealthCheck: append Ok or Ko line
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
internal/runner/healthcheck_test.go (1)
27-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the PDCP tool argument.
The mock verifies
keyandserverbut ignorestool. Since the PDCP client usestoolNameto build the request URL, a regression passing the wrong binary name would still pass this test. (github.com) Capture the argument and assertconfig.BinaryName(currently"nuclei").🤖 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 `@internal/runner/healthcheck_test.go` around lines 27 - 30, Update the mock credentials callback in the healthcheck test to assert that its tool argument matches config.BinaryName, currently "nuclei", alongside the existing key and server assertions. Ensure the callback captures and validates the tool value so incorrect binary names fail the test.
🤖 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 `@internal/runner/healthcheck.go`:
- Around line 90-94: Update appendPDCPHealthCheck’s getCreds error handling to
return silently only for pdcpauth.ErrNoCreds; propagate other credential
retrieval errors through the existing PDCP healthcheck failure format. Add a
regression test covering a non-ErrNoCreds retrieval failure and verifying it is
reported as a healthcheck failure.
---
Nitpick comments:
In `@internal/runner/healthcheck_test.go`:
- Around line 27-30: Update the mock credentials callback in the healthcheck
test to assert that its tool argument matches config.BinaryName, currently
"nuclei", alongside the existing key and server assertions. Ensure the callback
captures and validates the tool value so incorrect binary names fail the test.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d6512372-0a22-4f19-ac78-a00504f88e5a
📒 Files selected for processing (2)
internal/runner/healthcheck.gointernal/runner/healthcheck_test.go
| creds, err := getCreds() | ||
| if err != nil { | ||
| // Only check when an API key is configured. | ||
| return | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate healthcheck.go =="
fd -a 'healthcheck\.go$' . || true
echo "== file excerpt =="
if [ -f internal/runner/healthcheck.go ]; then
nl -ba internal/runner/healthcheck.go | sed -n '1,180p'
fi
echo "== getCreds references =="
rg -n "func getCreds|getCreds\\(|ErrNoCreds|PDCP API|pdcp" internal/runner go.mod || true
echo "== relevant go.mod =="
if [ -f go.mod ]; then
rg -n "projectdiscovery/utils|pdcp|auth" go.mod go.sum || true
fiRepository: projectdiscovery/nuclei
Length of output: 298
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== file excerpt =="
sed -n '1,180p' internal/runner/healthcheck.go | cat -n
echo "== getCreds references =="
rg -n "func getCreds|getCreds\\(|ErrNoCreds|PDCP API|pdcp|GetCreds" internal/runner go.mod go.sum || true
echo "== relevant go.mod =="
if [ -f go.mod ]; then
sed -n '1,160p' go.mod | cat -n
fiRepository: projectdiscovery/nuclei
Length of output: 16501
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== healthcheck tests =="
sed -n '1,120p' internal/runner/healthcheck_test.go | cat -n
echo "== projectdiscovery/utils v0.11.1 creds API =="
python3 <<'PY'
import urllib.request
urls = [
"https://raw.githubusercontent.com/projectdiscovery/utils/v0.11.1/auth/pdcp/creds.go",
"https://raw.githubusercontent.com/projectdiscovery/utils/v0.11.1/auth/pdcp/apikey.go",
]
for url in urls:
print(f"\n--- {url} ---")
try:
data = urllib.request.urlopen(url, timeout=20).read().decode()
for i, line in enumerate(data.splitlines(), 1):
if "ErrNoCreds" in line or "GetCreds" in line or "ValidateAPIKey" in line or "func " in line or "return errors" in line:
print(f"{i:4}: {line}")
except Exception as e:
print(f"ERROR: {e}")
PYRepository: projectdiscovery/nuclei
Length of output: 2555
🌐 Web query:
github.com projectdiscovery utils v0.11.1 auth/pdcp creds.go GetCreds ErrNoCreds
💡 Result:
In the projectdiscovery/utils library (v0.11.1), ErrNoCreds is a sentinel error used within the auth/pdcp package [1][2]. It is returned by the GetCreds method of the PDCPCredHandler struct when no valid credentials (such as an API key) are found, typically in the local ~/.pdcp/credential file [1][2]. Tools that utilize projectdiscovery/utils, such as Nuclei and interactsh, commonly use this error to detect missing authentication and trigger a flow to prompt the user to configure their API key or authenticate via a command-line flag [1][2]. For example, when a user provides an API key via a command-line flag, the application uses PDCPCredHandler to attempt to retrieve existing credentials [1][2]. If GetCreds returns pdcp.ErrNoCreds, the application then proceeds to validate the provided key and save it to the configuration file [1][2]. Technical implementation details can be summarized as follows: - Package: github.com/projectdiscovery/utils/auth/pdcp [3][4] - Error: pdcp.ErrNoCreds - Method: (*PDCPCredHandler).GetCreds [1][2]
Citations:
- 1: https://github.com/projectdiscovery/nuclei/blob/dev/cmd/nuclei/main.go
- 2: https://github.com/projectdiscovery/interactsh/blob/main/cmd/interactsh-client/main.go
- 3: https://github.com/projectdiscovery/nuclei/blob/4eb0b22a/internal/pdcp/utils.go
- 4: https://github.com/projectdiscovery/httpx/blob/faac44cc/internal/pdcp/utils.go
🌐 Web query:
github.com projectdiscovery utils auth/pdcp creds.go GetCreds ErrNoCreds
💡 Result:
In the ProjectDiscovery utils library, ErrNoCreds is a sentinel error defined within the auth/pdcp package [1][2][3]. It is returned by the GetCreds() method of the PDCPCredHandler struct when no valid PDCP (ProjectDiscovery Cloud Platform) credentials are found in the local configuration store [1][4][3]. When building tools that rely on ProjectDiscovery services (such as Nuclei or interactsh), this error is commonly encountered when a tool attempts to access cloud-authenticated features—like AI template generation or cloud result uploads—without prior authentication [1][3][5]. If you encounter ErrNoCreds or the associated runtime message "no credentials found," you can resolve it using one of the following methods: 1. Environment Variable: Set the PDCP_API_KEY environment variable in your terminal session [4]. - Linux/macOS: export PDCP_API_KEY=your_api_key_here - Windows PowerShell: $env:PDCP_API_KEY = "your_api_key_here" 2. Authentication Flag: Use the tool's -auth flag to provide your API key or trigger the interactive authentication flow [1][5]. For example, running nuclei -auth will typically prompt you to configure your credentials [1]. The PDCPCredHandler searches for credentials in the default .pdcp directory on the user's machine [4]. If the file is missing or contains no credentials, GetCreds() returns ErrNoCreds [1][3]. Developers integrating these utilities should check for this specific error to handle unauthenticated states gracefully, such as by prompting the user for credentials or falling back to a limited feature set [1][3][5].
Citations:
- 1: https://github.com/projectdiscovery/nuclei/blob/dev/cmd/nuclei/main.go
- 2: https://github.com/projectdiscovery/vulnx/blob/main/client.go
- 3: https://github.com/projectdiscovery/nuclei/blob/2d840752/internal/runner/runner.go
- 4: [BUG] ...[FTL] Could not run nuclei: Could not create loader.: [:RUNTIME] Failed to generate template: [:RUNTIME] Failed to get PDCP credentials: no credentials found in C:\Users\*\.pdcp #6050
- 5: https://github.com/projectdiscovery/interactsh/blob/main/cmd/interactsh-client/main.go
🌐 Web query:
github.com projectdiscovery/utils v0.11.1 auth/pdcp credentials file read yaml error ErrNoCreds
💡 Result:
The error ErrNoCreds is a standard sentinel error defined in the projectdiscovery/utils library's auth/pdcp package [1][2][3]. It is raised when the application attempts to retrieve user credentials (typically for ProjectDiscovery Cloud Platform, or PDCP) but cannot locate a valid credentials file or configuration [1][2][3]. This error is not typically a "YAML error" in the sense of a syntax failure; rather, it indicates that the expected credentials file (often located at ~/.pdcp/credentials.yaml) is missing, empty, or inaccessible [2][4]. To resolve this issue: 1. Authentication: Ensure you have authenticated with the tool using the appropriate flag, typically -auth [2][5]. For example, running tool_name -auth will prompt you to enter your API key, which will then be validated and saved to the standard credentials file [2][5]. 2. Environment Variables: You can bypass the file-based configuration by setting the PDCP_API_KEY environment variable directly [2][3]. 3. Debugging: If you are seeing this error in logs, it is often handled internally by the application (e.g., nuclei) [1]. The application detects ErrNoCreds and, if not in silent mode, informs the user to configure their API key to enable cloud-dependent features like result uploading [1]. If you are encountering a parsing error specifically while loading a custom YAML file, it is likely distinct from the ErrNoCreds sentinel error and would instead involve standard YAML unmarshaling failures within the application's configuration loader [6].
Citations:
- 1: https://github.com/projectdiscovery/nuclei/blob/3fdc06bc/internal/runner/runner.go
- 2: https://github.com/projectdiscovery/nuclei/blob/dev/cmd/nuclei/main.go
- 3: https://github.com/projectdiscovery/nuclei/blob/3fdc06bc/cmd/nuclei/main.go
- 4: add option to load credentials from command httpx#1905
- 5: https://github.com/projectdiscovery/interactsh/blob/main/cmd/interactsh-client/main.go
- 6: https://github.com/projectdiscovery/nuclei/blob/4eb0b22a/pkg/authprovider/authx/file.go
🌐 Web query:
"projectdiscovery/utils" "auth/pdcp" "ErrNoCreds" "yaml" "GetCreds"
💡 Result:
The error ErrNoCreds in the context of projectdiscovery/utils and auth/pdcp indicates that the tool (such as Nuclei or interactsh-client) could not locate the required ProjectDiscovery Cloud Platform (PDCP) credentials, which are typically stored in a .pdcp configuration file [1][2][3]. The GetCreds function in the pdcp.PDCPCredHandler struct is responsible for retrieving these credentials [1][2]. When this function returns pdcp.ErrNoCreds, it means the application has failed to find valid authentication data in the expected directory (commonly ~/.pdcp) [3]. To resolve this issue, you can use one of the following methods to authenticate: 1. Use the CLI Authentication Command: Run the tool with the -auth flag (e.g., nuclei -auth). This will prompt you to enter your PDCP API key, which will then be validated and saved to the configuration file [1][2][4]. 2. Set Environment Variables: You can provide the API key directly via the PDCP_API_KEY environment variable [3][4]. This is often used as a workaround in automated environments or when the local configuration file is missing [3]. - Windows Command Prompt: set PDCP_API_KEY=your_api_key_here [3] - PowerShell: $env:PDCP_API_KEY = "your_api_key_here" [3] - Linux/macOS: export PDCP_API_KEY=your_api_key_here [4] The ErrNoCreds error is frequently encountered when using features that require cloud platform integration, such as AI-powered template generation or uploading scan results to the PDCP dashboard [1][3]. If the tool requires these features, it will check for the presence of valid credentials and terminate with an error if they are missing [1][5]. Ensure that you have created an API key via your account at https://cloud.projectdiscovery.io before attempting to authenticate [4][6].
Citations:
- 1: https://github.com/projectdiscovery/nuclei/blob/dev/cmd/nuclei/main.go
- 2: https://github.com/projectdiscovery/interactsh/blob/main/cmd/interactsh-client/main.go
- 3: [BUG] ...[FTL] Could not run nuclei: Could not create loader.: [:RUNTIME] Failed to generate template: [:RUNTIME] Failed to get PDCP credentials: no credentials found in C:\Users\*\.pdcp #6050
- 4: https://docs.projectdiscovery.io/cloud/scanning/internal-scan
- 5: https://github.com/projectdiscovery/nuclei/blob/4eb0b22a/internal/pdcp/writer.go
- 6: https://projectdiscovery-nuclei-v3-2-3-updates.mintlify.app/api-reference/introduction
🌐 Web query:
"json.Unmarshal" "ErrNoCreds" "yaml" "GetCreds" "PDCPCredHandler"
💡 Result:
The terms and symbols you referenced pertain to the credential management system used in ProjectDiscovery tools, such as Nuclei and Interactsh [1][2]. In this architecture: 1. PDCPCredHandler is a Go struct responsible for managing ProjectDiscovery Cloud Platform (PDCP) credentials [1][2]. 2. GetCreds is a method on the PDCPCredHandler that attempts to retrieve saved authentication credentials [1][2]. 3. ErrNoCreds is a specific error value returned by the GetCreds method when no valid credentials are found (e.g., in the expected configuration file) [1][2]. In the context of the code you provided, developers use this handler to check for existing authentication [1][2]. If GetCreds returns ErrNoCreds, the application typically proceeds to either prompt the user for an API key or perform an alternative authentication flow using an API key provided via flags or environment variables [1][2]. Regarding json.Unmarshal and YAML, these are commonly used in Go to parse configuration files [3][4]. If you are encountering an issue combining these with credential management, it is likely that: - The application is attempting to parse a configuration file or credential store using a YAML unmarshaler [3][4]. - If the configuration is in JSON format, using yaml.Unmarshal may occasionally fail or produce unexpected results because while YAML is a superset of JSON, some strict JSON syntax (like certain escape sequences) may not be perfectly handled by all YAML library versions [4]. If you are seeing an error during this process, ensure that the data being passed to the unmarshaler matches the expected format (JSON vs YAML) or use the appropriate library (json.Unmarshal for JSON, yaml.Unmarshal for YAML) to prevent parsing errors [3][4].
Citations:
- 1: https://github.com/projectdiscovery/nuclei/blob/dev/cmd/nuclei/main.go
- 2: https://github.com/projectdiscovery/interactsh/blob/main/cmd/interactsh-client/main.go
- 3: https://stackoverflow.com/questions/68156758/robust-way-check-if-the-input-is-json-or-yaml
- 4: yaml.Unmarshal does not support optional string escapes for JSON hairyhenderson/gomplate#1349
Distinguish missing PDCP credentials from retrieval failures.
appendPDCPHealthCheck currently returns early for any credential-loading error, so a corrupted or unreadable credential store is hidden as “credentials not configured” instead of a PDCP healthcheck failure. Skip only pdcpauth.ErrNoCreds; report other errors with the existing PDCP failure format and add a regression test for retrieval failures.
Proposed fix
if err != nil {
- // Only check when an API key is configured.
- return
+ if err == pdcpauth.ErrNoCreds {
+ return
+ }
+ fmt.Fprintf(test, "PDCP API => Ko (%s)\n", err)
+ return
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| creds, err := getCreds() | |
| if err != nil { | |
| // Only check when an API key is configured. | |
| return | |
| } | |
| creds, err := getCreds() | |
| if err != nil { | |
| if err == pdcpauth.ErrNoCreds { | |
| return | |
| } | |
| fmt.Fprintf(test, "PDCP API => Ko (%s)\n", err) | |
| return | |
| } |
🤖 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 `@internal/runner/healthcheck.go` around lines 90 - 94, Update
appendPDCPHealthCheck’s getCreds error handling to return silently only for
pdcpauth.ErrNoCreds; propagate other credential retrieval errors through the
existing PDCP healthcheck failure format. Add a regression test covering a
non-ErrNoCreds retrieval failure and verifying it is reported as a healthcheck
failure.
Summary
Summary by CodeRabbit
New Features
Bug Fixes
Tests