Help us improve
Share bugs, ideas, or general feedback.
From ai-plugins
Use when user asks to setup endorctl, install endorctl, run endorctl scan, scan for vulnerabilities, run endor scan or run Endor Labs scan or when any endorctl command fails with 'command not found', 'no such file or directory', authentication errors, 'unauthorized', '403', 'tenant not found', EOF error, or namespace/access errors.
npx claudepluginhub endorlabs/ai-plugins --plugin ai-pluginsHow this skill is triggered — by the user, by Claude, or both
Slash command
/ai-plugins:endor-setupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Prerequisite skill that ensures endorctl is installed, authenticated, and configured before any Endor Labs operation.
Conducts security audits for DevSecOps, reviews SDLC controls, CI/CD pipelines, threat models, vulnerabilities, authentication, authorization, and compliance frameworks.
Scans local projects for dependency vulnerabilities (SCA), code security patterns (SAST), leaked secrets, auth/crypto flaws, misconfigs, supply chain risks, CI/CD issues. Generates prioritized report with remediation guidance.
Drafts personalized cold emails, warm intros, follow-ups, updates, and communications for investor outreach during fundraising to angels, VCs, accelerators.
Share bugs, ideas, or general feedback.
Prerequisite skill that ensures endorctl is installed, authenticated, and configured before any Endor Labs operation.
When the user asks to set up endorctl and run basic scan, follow this sequence:
Check if endorctl is installed (Step 1)
ALWAYS ask for namespace BEFORE authentication (Step 3) - This is CRITICAL for CLI authentication to work in non-interactive environments. The namespace must be collected first so it can be passed to endorctl init --namespace=<namespace> to avoid interactive tenant selection prompts.
Never fail with "command not found" - always install endorctl if missing
Key principle: Be proactive. If endorctl is missing, install it automatically rather than asking the user to install it themselves.
Namespace hierarchy: Users can scan on parent tenants or child namespaces (format: parent.child). Always accept the namespace the user provides.
Access errors: If the user doesn't have access to a tenant/namespace, clearly inform them they lack access and suggest they verify permissions or try a different namespace.
Auto-fetch documentation: When fetching scan options from docs.endorlabs.com, fetch it automatically. This is a trusted documentation source.
CRITICAL - Non-interactive environment: AI coding agents run in a non-interactive CLI environment. Commands that require interactive input (like tenant selection prompts) will fail with EOF errors. Always use flags to provide values upfront instead of relying on interactive prompts.
Multi-tenant users: Users with access to multiple Endor Labs tenants require special handling during Browser OAuth. The --namespace flag alone does NOT prevent the interactive tenant selection prompt. You must capture the tenant list and pipe the tenant number to complete authentication in a single flow. See Step 4 for details.
Use the API endpoint from the existing config file if present. If no config exists, default to production:
# If config exists, use its ENDOR_API value; otherwise default to production
export ENDOR_API=${ENDOR_API:-https://api.endorlabs.com}
IMPORTANT: If the user asks to run endorctl scan and it's not installed, do NOT just report an error. Instead, follow this workflow to install it first.
Run these checks together to determine the user's state:
# Check if installed
if ! command -v endorctl &> /dev/null; then
echo "NOT_INSTALLED"
else
endorctl --version
fi
# Check if already authenticated (config file exists with credentials)
if [ -f ~/.endorctl/config.yaml ]; then
echo "CONFIG_EXISTS"
# Extract ENDOR_API from config (do NOT cat the full file)
ENDOR_API=$(grep 'api:' ~/.endorctl/config.yaml | awk '{print $2}')
export ENDOR_API=${ENDOR_API:-https://api.endorlabs.com}
echo "ENDOR_API=$ENDOR_API"
else
echo "NOT_AUTHENTICATED"
export ENDOR_API=https://api.endorlabs.com
fi
Decision tree based on results:
NOT_INSTALLED: Immediately go to Step 2 (Download) - DO NOT ask the user, just proceed with installationCONFIG_EXISTS: User is already authenticated → The ENDOR_API has been extracted using the grep command above. Go to Step 3 (Ask for Namespace). Do NOT run cat on the config file.NOT_AUTHENTICATED: Go to Step 4 (Authenticate), then Step 3 (Ask for Namespace)CRITICAL: The config file check is ONLY to determine if authentication is already set up. Even if a namespace exists in the config, you MUST still ask the user which namespace they want to use before running the scan. Never assume the namespace from the config file.
When to execute: Automatically execute this step if Step 1 shows "NOT_INSTALLED".
IMPORTANT: On macOS, ALWAYS ask the user which installation method they prefer before proceeding:
Present these two options using AskUserQuestion:
brew tap endorlabs/tap && brew install endorctl. Easier to update later.brew tap endorlabs/tap
brew install endorctl
ARCH=$(uname -m)
case "$ARCH" in
x86_64|amd64) ARCH="amd64" ;;
arm64|aarch64) ARCH="arm64" ;;
esac
BINARY="endorctl_macos_${ARCH}"
echo "Downloading $BINARY..."
curl -L "https://api.endorlabs.com/download/latest/$BINARY" -o endorctl
# Verify checksum
EXPECTED_SHA=$(curl -s "https://api.endorlabs.com/sha/latest/$BINARY")
echo "$EXPECTED_SHA endorctl" | shasum -a 256 -c
chmod +x ./endorctl
# Install to ~/bin
mkdir -p ~/bin
mv endorctl ~/bin/
export PATH="$HOME/bin:$PATH"
For Linux and Windows, proceed with direct download automatically:
#!/bin/bash
set -e
OS=$(uname -s)
ARCH=$(uname -m)
# Normalize OS names
case "$OS" in
Linux*)
OS="linux"
;;
MINGW*|MSYS*|CYGWIN*)
OS="windows"
;;
*)
echo "Unsupported operating system: $OS"
exit 1
;;
esac
# Normalize architecture names
case "$ARCH" in
x86_64|amd64)
ARCH="amd64"
;;
arm64|aarch64)
ARCH="arm64"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
echo "Detected platform: $OS $ARCH"
# Build download URL
if [ "$OS" = "windows" ]; then
BINARY="endorctl_windows_${ARCH}.exe"
OUTPUT="endorctl.exe"
else
BINARY="endorctl_${OS}_${ARCH}"
OUTPUT="endorctl"
fi
echo "Downloading $BINARY..."
curl -L "https://api.endorlabs.com/download/latest/$BINARY" -o "$OUTPUT"
# Verify checksum
echo "Verifying checksum..."
EXPECTED_SHA=$(curl -s "https://api.endorlabs.com/sha/latest/$BINARY")
echo "$EXPECTED_SHA $OUTPUT" | sha256sum -c
# Make executable (not needed for .exe)
if [ "$OS" != "windows" ]; then
chmod +x "./$OUTPUT"
fi
echo "Installation complete!"
echo "Binary location: $(pwd)/$OUTPUT"
After download completes, move the binary to PATH:
# Install to ~/bin
mkdir -p ~/bin
mv endorctl ~/bin/ # or endorctl.exe on Windows
export PATH="$HOME/bin:$PATH"
Since shell state does not persist between commands, you MUST prefix export PATH="$HOME/bin:$PATH" in every subsequent Bash command that uses endorctl (if it was installed to ~/bin).
After installing endorctl, verify that the download and installation succeeded:
export PATH="$HOME/bin:$PATH"
endorctl --version
If this command prints the version information, endorctl has been downloaded and verified successfully. If it fails, retry the installation steps above.
IMPORTANT: ALWAYS ask the user for their Endor Labs namespace before running a scan, even if a namespace already exists in the config file.
Endor Labs supports hierarchical namespaces (parent/child structure):
parent)parent.child-project)Users can run scans on:
parent.child)Example child namespace usage:
# Scan using parent namespace
endorctl scan --namespace=parent
# Scan using child namespace
endorctl scan --namespace=parent.my-project
IMPORTANT: If the user does not have access to a tenant or namespace, endorctl will return an access error. When this happens:
Invalid permissions to run endorctl - User lacks access to the namespaceunauthorized or 403 errors - Authentication succeeded but authorization failed for that namespacetenant not found - The namespace doesn't exist or user has no visibility to itSet via environment variable:
export ENDOR_NAMESPACE=<user-provided-namespace>
Or pass as flag in scan command:
endorctl scan --namespace=<user-provided-namespace>
IMPORTANT: You must have already collected the namespace in Step 3 BEFORE running authentication. This is required to avoid interactive prompts.
Ask the user using AskUserQuestion with two options:
If the user selects CLI Authentication, ask which identity provider they use. Present these options using AskUserQuestion:
Based on the user's selection, use the corresponding --auth-mode value:
| Provider | --auth-mode value | Additional Flags |
|---|---|---|
google | None | |
| GitHub | github | None |
| GitLab | gitlab | None |
| Enterprise SSO | sso | --auth-tenant <tenant-name> |
| Browser (generic) | browser-auth | None |
For Enterprise SSO only: After the user selects SSO, also ask them for their SSO tenant name:
"What is your SSO tenant name? (This is used with --auth-tenant)"
CRITICAL - Multi-Tenant Handling: Users with access to multiple tenants will be prompted to select a tenant interactively. In non-interactive environments (like Claude Code), this causes an EOF error. The --namespace flag alone does NOT prevent this prompt. This applies to ALL browser-based auth modes.
Construct the AUTH_FLAGS based on the user's provider selection:
# Set AUTH_FLAGS based on user's provider selection
# Google: AUTH_FLAGS="--auth-mode=google"
# GitHub: AUTH_FLAGS="--auth-mode=github"
# GitLab: AUTH_FLAGS="--auth-mode=gitlab"
# Enterprise SSO: AUTH_FLAGS="--auth-mode=sso --auth-tenant=<tenant-name>"
# Browser (generic): AUTH_FLAGS="--auth-mode=browser-auth"
Step 4c-i: Initiate browser oauth and capture tenant list
Run init and capture output — this will open the browser for OAuth. After browser auth completes, it will show a tenant list if the user has multiple tenants.
IMPORTANT: Use a timeout to prevent the command from blocking indefinitely at the interactive tenant selection prompt. The shell tool in AI coding agents (Cursor, Claude Code, etc.) cannot provide interactive input to a running process. The timeout ensures the command exits so the agent can parse the output and proceed to Step 4c-ii.
# Run init with a timeout (60s allows time for browser OAuth, but won't hang forever at the tenant prompt)
# The timeout will kill the process after 60 seconds if it's still waiting for input
timeout 60 bash -c 'endorctl init $AUTH_FLAGS --namespace=<user-provided-namespace> 2>&1' | tee /tmp/endorctl_init_output.txt || true
After this command completes (either successfully or via timeout/EOF), check the captured output:
# Check if tenant selection was required
if grep -q "Please select the tenant" /tmp/endorctl_init_output.txt; then
echo "MULTI_TENANT_DETECTED"
cat /tmp/endorctl_init_output.txt
fi
If the output shows a tenant list like:
Your account has access to multiple tenants. Please select the tenant you would like to initialize:
0 : tenant-a [SYSTEM_ROLE_ADMIN]
1 : tenant-b [SYSTEM_ROLE_READ_ONLY]
2 : my-namespace [SYSTEM_ROLE_ADMIN]
Enter tenant number:
Then proceed immediately to Step 4c-ii.
Step 4c-ii: Re-run with tenant number piped in
Parse the captured output to find the tenant number matching the user's requested namespace. The tenant number is the number before the : on the line containing the namespace name.
# Parse the tenant number from the captured output
# Example: for namespace "qa-test", find the line "15 : qa-test [SYSTEM_ROLE_ADMIN]" and extract "15"
TENANT_NUM=$(grep -E "^\s*[0-9]+ : <user-provided-namespace> " /tmp/endorctl_init_output.txt | awk '{print $1}')
echo "Found tenant number: $TENANT_NUM"
# Re-run with tenant number piped via stdin (no tee needed this time)
echo "$TENANT_NUM" | endorctl init $AUTH_FLAGS --namespace=<user-provided-namespace>
IMPORTANT: The echo "$TENANT_NUM" | syntax pipes the tenant number into stdin, which is more portable across shell environments than <<<. This avoids the interactive prompt entirely on the second run.
If authentication still fails (e.g., user doesn't have access to the specified namespace):
Instruct the user to set these environment variables themselves (never ask them to paste credentials into chat):
export ENDOR_API_CREDENTIALS_KEY=<your-api-key>
export ENDOR_API_CREDENTIALS_SECRET=<your-api-secret>
No init needed - scan will use these credentials directly.
Note: API Key authentication avoids interactive prompts entirely and works best in automated/CLI environments. This is the recommended approach for users who frequently encounter multi-tenant selection issues.
IMPORTANT: When the user requests a specific type of scan (e.g., "quick scan", "secrets scan", "SAST scan", "container scan", etc.), you MUST fetch the current scan options from the documentation before running the scan.
User requests a specific scan type (e.g., "run a quick scan", "scan for secrets", "run SAST")
Fetch documentation automatically using WebFetch (do NOT ask for permission - just fetch):
URL: https://docs.endorlabs.com/endorctl/commands/scan/
Prompt: "Find the flag/option for [user's requested scan type] scan"
Note: Fetching from docs.endorlabs.com should be done automatically without prompting the user for confirmation.
Extract the correct flag from the documentation (e.g., --quick-scan, --secrets, --sast)
Run the scan with the appropriate flag(s)
User: "Can you run a quick scan on this repo?"
Step 1: Fetch docs
→ WebFetch("https://docs.endorlabs.com/endorctl/commands/scan/", "Find the flag for quick scan")
Step 2: Extract flag from docs
→ Found: --quick-scan
Step 3: Run scan with flag
→ endorctl scan --namespace=$ENDOR_NAMESPACE --quick-scan
# Default scan (no specific type requested)
endorctl scan --namespace=$ENDOR_NAMESPACE
# With specific scan type (fetch flag from docs first!)
endorctl scan --namespace=$ENDOR_NAMESPACE <flags-from-docs>
IMPORTANT:
For first-time users:
endorctl init --auth-mode=<mode> --namespace=<namespace> (MUST include namespace to avoid interactive prompts). For SSO, also collect --auth-tenant.endorctl scan --namespace=<namespace>For returning users (already authenticated):
endorctl scan --namespace=<namespace>CRITICAL REMINDER: The namespace MUST be collected BEFORE running endorctl init with Browser OAuth. This prevents EOF errors from interactive tenant selection prompts in non-interactive environments like Claude Code.