-
Notifications
You must be signed in to change notification settings - Fork 56
Releasing Puppet integration v1.0.2 #776
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Initial Puppet Integration
- Rename module from `keeper_secret_manager_puppet` to `keeper_secrets_manager_puppet` (plural form) - Fix PowerShell command syntax error - missing closing quote in `install_ksm.pp` - Looks like it was never tested on Windows - Update `metadata.json` with correct GitHub URLs and MIT license - Update all module references throughout codebase to use new plural name - Update Ruby constants module name to match new naming convention
…tion/puppet/v1.0.0-fixed
…ts_manager_puppet in lookup.rb, config.pp files (#775)
runs-on: ubuntu-latest | ||
steps: | ||
- name: Get the source code | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install Syft | ||
run: | | ||
echo "Installing Syft v1.18.1..." | ||
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /tmp/bin v1.18.1 | ||
echo "/tmp/bin" >> $GITHUB_PATH | ||
|
||
- name: Install Manifest CLI | ||
run: | | ||
echo "Installing Manifest CLI v0.18.3..." | ||
curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -s -- -b /tmp/bin v0.18.3 | ||
|
||
- name: Create Syft configuration | ||
run: | | ||
cat > syft-config.yaml << 'EOF' | ||
package: | ||
search: | ||
scope: all-layers | ||
exclude: | ||
- "**/spec/**" | ||
- "**/examples/**" | ||
- "**/tests/**" | ||
cataloger: | ||
enabled: true | ||
ruby: | ||
enabled: true | ||
search-gems: true | ||
java: | ||
enabled: false | ||
python: | ||
enabled: false | ||
nodejs: | ||
enabled: false | ||
EOF | ||
|
||
- name: Generate and upload SBOM | ||
env: | ||
MANIFEST_API_KEY: ${{ secrets.MANIFEST_TOKEN }} | ||
run: | | ||
PUPPET_MODULE_DIR="./integration/keeper_secrets_manager_puppet" | ||
|
||
# Get version from metadata.json | ||
echo "Detecting Puppet module version..." | ||
if [ -f "${PUPPET_MODULE_DIR}/metadata.json" ]; then | ||
VERSION=$(cat "${PUPPET_MODULE_DIR}/metadata.json" | jq -r .version) | ||
echo "Detected version: ${VERSION}" | ||
else | ||
VERSION="1.0.0" | ||
echo "Could not detect version, using default: ${VERSION}" | ||
fi | ||
|
||
echo "Generating SBOM with Manifest CLI..." | ||
/tmp/bin/manifest sbom "${PUPPET_MODULE_DIR}" \ | ||
--generator=syft \ | ||
--name=keeper-secrets-manager-puppet \ | ||
--version=${VERSION} \ | ||
--output=spdx-json \ | ||
--file=puppet-module-sbom.json \ | ||
--api-key=${MANIFEST_API_KEY} \ | ||
--publish=true \ | ||
--asset-label=application,sbom-generated,ruby,puppet \ | ||
--generator-config=syft-config.yaml | ||
|
||
echo "SBOM generated and uploaded successfully: puppet-module-sbom.json" | ||
echo "---------- SBOM Preview (first 20 lines) ----------" | ||
head -n 20 puppet-module-sbom.json | ||
|
||
publish-puppet-forge: |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
To fix the problem, add a permissions
block to the workflow file to explicitly set the minimum required permissions for the GITHUB_TOKEN. Since the workflow does not appear to require write access to repository contents or other resources, the minimal permission of contents: read
is appropriate. This should be added at the top level of the workflow file (after the name
and on
keys), so it applies to all jobs unless overridden. No changes to the jobs themselves are necessary unless a job requires additional permissions.
-
Copy modified lines R5-R7
@@ -4,2 +4,5 @@ | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: |
# -------------------- Logging & Custom Exceptions -------------------- | ||
|
||
def log_message(level, message): | ||
print(f"[{level}] KEEPER: {message}", file=sys.stderr) |
Check failure
Code scanning / CodeQL
Clear-text logging of sensitive information High
sensitive data (secret)
This expression logs
sensitive data (secret)
This expression logs
sensitive data (secret)
This expression logs
sensitive data (secret)
This expression logs
sensitive data (secret)
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
To fix the problem, we should avoid logging the full keeper notation string in error messages, especially when an exception occurs during secret processing. Instead, we can log a generic error message or, if necessary, log only non-sensitive metadata (such as the type of error or a generic identifier). Specifically, in the process_secret_notation
function, the error log on line 270 should be changed to avoid including the potentially sensitive keeper_notation
. The rest of the logging logic can remain unchanged, as long as no sensitive data is included in log messages.
Required changes:
- In
process_secret_notation
, replace the log message on line 270 to avoid logging the keeper notation string. - No new imports are needed.
- No changes to the logging function itself are required.
-
Copy modified line R270
@@ -269,3 +269,3 @@ | ||
except Exception as e: | ||
log_message("ERROR", f"Failed to process keeper notation '{keeper_notation}': {e}") | ||
log_message("ERROR", f"Failed to process keeper notation: {e}") | ||
raise |
env_path = os.path.join(Constants.DEFAULT_PATH, Constants.ENV_FILE) | ||
os.makedirs(Constants.DEFAULT_PATH, exist_ok=True) | ||
with open(env_path, "a") as env_file: | ||
env_file.write(f'export {output_name}="{value}"\n') |
Check failure
Code scanning / CodeQL
Clear-text storage of sensitive information High
sensitive data (secret)
This expression stores
sensitive data (secret)
This expression stores
sensitive data (secret)
This expression stores
sensitive data (secret)
This expression stores
sensitive data (secret)
… metadata.json; enhance GitHub Actions workflow with improved error handling and validation steps
…0-fixed' into release/integration/puppet/v1.0.0-fixed
needs: generate-sbom | ||
environment: prod | ||
runs-on: ubuntu-latest | ||
timeout-minutes: 15 | ||
|
||
defaults: | ||
run: | ||
working-directory: ./integration/keeper_secrets_manager_puppet | ||
|
||
steps: | ||
- name: Get the source code | ||
uses: actions/checkout@v4 | ||
|
||
- name: Setup Ruby with version from .ruby-version | ||
uses: ruby/setup-ruby@v1 | ||
with: | ||
ruby-version: '3.2.4' | ||
bundler-cache: true | ||
working-directory: ./integration/keeper_secrets_manager_puppet | ||
|
||
- name: Retrieve secrets from KSM | ||
id: ksmsecrets | ||
uses: Keeper-Security/ksm-action@master | ||
with: | ||
keeper-secret-config: ${{ secrets.KSM_KSM_CONFIG }} | ||
secrets: | | ||
_gC1qMMHRcD6Fztyd692kw/field/password > PUPPET_FORGE_API_KEY | ||
|
||
- name: Get current version and validate | ||
id: version | ||
run: | | ||
if [[ -f "metadata.json" ]]; then | ||
VERSION=$(grep '"version"' metadata.json | cut -d'"' -f4) | ||
echo "current_version=$VERSION" >> $GITHUB_OUTPUT | ||
echo "Current version: $VERSION" | ||
else | ||
echo "Error: metadata.json not found" | ||
exit 1 | ||
fi | ||
|
||
- name: Check if version already exists on Puppet Forge | ||
env: | ||
VERSION: ${{ steps.version.outputs.current_version }} | ||
run: | | ||
echo "Checking if version $VERSION already exists on Puppet Forge..." | ||
FORGE_CHECK=$(curl -s "https://forgeapi.puppet.com/v3/releases/keepersecurity-keeper_secrets_manager_puppet-$VERSION") | ||
|
||
if echo "$FORGE_CHECK" | grep -q '"uri"'; then | ||
echo "Error: Version $VERSION already exists on Puppet Forge!" | ||
echo "" | ||
echo "To publish a new release, you need to:" | ||
echo "1. Bump the version in metadata.json" | ||
echo " File: integration/keeper_secrets_manager_puppet/metadata.json" | ||
echo " Current: \"version\": \"$VERSION\"" | ||
echo " Example: \"version\": \"1.0.3\" (for patch)" | ||
echo " \"version\": \"1.1.0\" (for minor)" | ||
echo " \"version\": \"2.0.0\" (for major)" | ||
echo "" | ||
echo "Version already published at: https://forge.puppet.com/modules/keepersecurity/keeper_secrets_manager_puppet" | ||
exit 1 | ||
fi | ||
echo "Version $VERSION is available for publishing" | ||
|
||
- name: Validate API key format | ||
env: | ||
PUPPET_FORGE_API_KEY: ${{ steps.ksmsecrets.outputs.PUPPET_FORGE_API_KEY }} | ||
run: | | ||
if [[ ! "$PUPPET_FORGE_API_KEY" =~ ^[a-f0-9]{64}$ ]]; then | ||
echo "Warning: API key format doesn't match expected pattern (64 hex characters)" | ||
echo "Key length: ${#PUPPET_FORGE_API_KEY}" | ||
echo "Continuing anyway, but check your key if publishing fails..." | ||
else | ||
echo "API key format looks correct" | ||
fi | ||
|
||
- name: Install dependencies | ||
run: | | ||
echo "Installing Ruby dependencies..." | ||
if ! bundle install; then | ||
echo "Failed to install dependencies" | ||
echo "Gem versions installed:" | ||
bundle list | ||
exit 1 | ||
fi | ||
echo "Dependencies installed successfully" | ||
|
||
# Show key dependency versions | ||
echo "Key dependency versions:" | ||
bundle list | grep -E "(puppet|rake|puppet-lint)" | ||
|
||
- name: Run comprehensive validation | ||
run: | | ||
echo "Running comprehensive validation..." | ||
|
||
# Run lint with error handling | ||
echo "Running puppet-lint..." | ||
if ! bundle exec rake lint; then | ||
echo "Lint failed" | ||
exit 1 | ||
fi | ||
echo "Lint passed" | ||
|
||
# Run validation | ||
echo "Running puppet validate..." | ||
if ! bundle exec rake validate; then | ||
echo "Validation failed" | ||
exit 1 | ||
fi | ||
echo "Validation passed" | ||
|
||
# Run metadata lint | ||
echo "Running metadata lint..." | ||
if ! bundle exec metadata-json-lint metadata.json; then | ||
echo "Metadata lint failed" | ||
exit 1 | ||
fi | ||
echo "Metadata validation passed" | ||
|
||
- name: Run full test suite | ||
run: | | ||
echo "Running full test suite..." | ||
if ! bundle exec rake spec; then | ||
echo "Tests failed" | ||
exit 1 | ||
fi | ||
echo "All tests passed" | ||
|
||
- name: Build module | ||
run: | | ||
echo "Building module..." | ||
if ! bundle exec rake module:build; then | ||
echo "Build failed" | ||
exit 1 | ||
fi | ||
echo "Module built successfully" | ||
|
||
# Show built packages | ||
echo "Built packages:" | ||
ls -la pkg/ | grep '.tar.gz' || echo "No packages found" | ||
|
||
- name: Publish to Puppet Forge with robust error handling | ||
env: | ||
PUPPET_FORGE_API_KEY: ${{ steps.ksmsecrets.outputs.PUPPET_FORGE_API_KEY }} | ||
VERSION: ${{ steps.version.outputs.current_version }} | ||
PDK_DISABLE_ANALYTICS: true | ||
run: | | ||
echo "Publishing to Puppet Forge..." | ||
|
||
cd pkg | ||
LATEST_FILE=$(ls -t keepersecurity-keeper_secrets_manager_puppet-*.tar.gz | head -1) | ||
|
||
if [[ -z "$LATEST_FILE" ]]; then | ||
echo "No package file found to publish" | ||
exit 1 | ||
fi | ||
|
||
echo "Publishing: $LATEST_FILE" | ||
|
||
RESULT=$(curl -s -X POST \ | ||
-H "Authorization: Bearer $PUPPET_FORGE_API_KEY" \ | ||
-F "file=@$LATEST_FILE" \ | ||
https://forgeapi.puppet.com/v3/releases) | ||
|
||
echo "$RESULT" | ||
|
||
if echo "$RESULT" | grep -q '"uri"'; then | ||
echo "" | ||
echo "Successfully published to Puppet Forge!" | ||
echo "Module available at: https://forge.puppet.com/modules/keepersecurity/keeper_secrets_manager_puppet" | ||
|
||
# Extract and display the published version info | ||
if echo "$RESULT" | grep -q '"version"'; then | ||
PUBLISHED_VERSION=$(echo "$RESULT" | grep -o '"version":"[^"]*"' | cut -d'"' -f4) | ||
echo "Published version: $PUBLISHED_VERSION" | ||
fi | ||
else | ||
echo "" | ||
echo "Failed to publish. Check the error message above." | ||
|
||
# Enhanced error handling with specific guidance | ||
if echo "$RESULT" | grep -q 'cannot publish releases'; then | ||
echo "" | ||
echo "API Key Issue: Your API key may not have permission to publish to the keepersecurity namespace." | ||
echo "Solutions:" | ||
echo "1. Verify you are using the correct API key from the keepersecurity organization" | ||
echo "2. Check that your API key has publish permissions" | ||
echo "3. Regenerate your API key at: https://forge.puppet.com/organization/api-keys" | ||
echo "4. Update the secret in GitHub: PUPPET_FORGE_API_KEY" | ||
elif echo "$RESULT" | grep -q -i 'version.*already.*exists\|duplicate.*version\|version.*conflict'; then | ||
echo "" | ||
echo "Version Conflict: This version already exists on Puppet Forge." | ||
echo "" | ||
echo "To publish a new release:" | ||
echo "1. Bump the version in metadata.json" | ||
echo " File: integration/keeper_secrets_manager_puppet/metadata.json" | ||
echo " Current: \"version\": \"$VERSION\"" | ||
echo " Example: \"version\": \"1.0.3\" (patch), \"1.1.0\" (minor), \"2.0.0\" (major)" | ||
echo "2. Commit and push the version change" | ||
echo "3. Re-run this workflow" | ||
elif echo "$RESULT" | grep -q -i 'unauthorized\|authentication'; then | ||
echo "" | ||
echo "Authentication Error: API key is invalid or expired." | ||
echo "Solutions:" | ||
echo "1. Check that PUPPET_FORGE_API_KEY secret is set correctly" | ||
echo "2. Regenerate API key at: https://forge.puppet.com/organization/api-keys" | ||
echo "3. Update the GitHub secret with the new key" | ||
else | ||
echo "" | ||
echo "Unknown error occurred. Please check the API response above." | ||
echo "For help, visit: https://forge.puppet.com/docs/publish" | ||
fi | ||
exit 1 | ||
fi | ||
|
||
- name: Create release summary | ||
env: | ||
VERSION: ${{ steps.version.outputs.current_version }} | ||
run: | | ||
echo "## Puppet Module Published Successfully!" >> $GITHUB_STEP_SUMMARY | ||
echo "" >> $GITHUB_STEP_SUMMARY | ||
echo "**Version:** $VERSION" >> $GITHUB_STEP_SUMMARY | ||
echo "**Module:** keepersecurity-keeper_secrets_manager_puppet" >> $GITHUB_STEP_SUMMARY | ||
echo "**Forge URL:** https://forge.puppet.com/modules/keepersecurity/keeper_secrets_manager_puppet" >> $GITHUB_STEP_SUMMARY | ||
echo "" >> $GITHUB_STEP_SUMMARY | ||
echo "### Validation Results" >> $GITHUB_STEP_SUMMARY | ||
echo "- Puppet Lint: Passed" >> $GITHUB_STEP_SUMMARY | ||
echo "- Puppet Validate: Passed" >> $GITHUB_STEP_SUMMARY | ||
echo "- Metadata Lint: Passed" >> $GITHUB_STEP_SUMMARY | ||
echo "- Test Suite: Passed" >> $GITHUB_STEP_SUMMARY | ||
echo "- Module Build: Successful" >> $GITHUB_STEP_SUMMARY | ||
echo "- Forge Publish: Successful" >> $GITHUB_STEP_SUMMARY No newline at end of file |
Check warning
Code scanning / CodeQL
Workflow does not contain permissions Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 3 months ago
To fix the problem, add a permissions
block to the workflow file. This can be done at the top level (applies to all jobs) or at the job level (applies to a specific job). Since neither job in this workflow appears to require write access to repository contents, the minimal and recommended fix is to add permissions: contents: read
at the top level, just below the name
and on
keys. This will ensure that the GITHUB_TOKEN used in all jobs has only read access to repository contents, adhering to the principle of least privilege.
-
Copy modified lines R5-R7
@@ -4,2 +4,5 @@ | ||
|
||
permissions: | ||
contents: read | ||
|
||
jobs: |
No description provided.