util-preparek8senv — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited util-preparek8senv (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Prepare Kubernetes infrastructure by generating K8s manifests for all 3rd party supporting applications for a single target environment. Manifests are generated directly in the environment/ folder (no per-environment subfolders). Since the environment/ folder is gitignored, each machine maintains its own independent copy of the manifests.
This skill accepts an optional <environment> argument:
/util-preparek8senv [environment]| Argument | Required | Example | Description |
|---|---|---|---|
<environment> | No | home_server | Target environment name — must match a Kubernetes environment in CLAUDE.md |
If omitted:
The environment name is matched case-insensitively against the environment headings in CLAUDE.md, accepting snake_case, kebab-case, or title-case input (e.g., home_server, home-server, Home Server all match ## Home Server).
All other configuration is read from the project root:
| File | Purpose | Required |
|---|---|---|
CLAUDE.md | Project detail, environments, 3rd party applications, rules | Yes |
ENVIRONMENT.md | Per-environment configs and credentials for 3rd party apps | Created if missing |
DEVTOOL.md | Local development tools (CLI paths for kubectl, mysql, mongosh, etc.) | Yes |
Read CLAUDE.md from the project root and extract:
# Project Detail → Project Code (e.g., URP). Used as K8s namespace (lowercase: urp).## <Environment Name> heading under # Environment is an environment. Extract:localhost, home_server)localhost, home.server) — from the - Domain: fieldManual, Kubernetes) — from the - Deployment Type: field## <Application Name> heading under # Supporting 3rd Party Applications. Extract:- Depends on: list)# Rules section — standard username/password format for new accounts.Stop conditions:
# Environment section is missing or has no environments → stop with error# Supporting 3rd Party Applications section is missing or has no entries → stop with errorDEVTOOL.md does not exist → stop with errorDeployment Type: Kubernetes → stop with error: "No Kubernetes environments found in CLAUDE.md. This skill only generates manifests for environments with Deployment Type: Kubernetes."After parsing all environments, identify Kubernetes environments and select the target:
Deployment Type: Kubernetes.<environment> argument, match it against the Kubernetes environments (case-insensitively, accepting snake_case, kebab-case, or title-case).The selected environment is the target environment used for Step 2 (ENVIRONMENT.md sync) and Step 3 (K8s manifest generation). Only this one environment is processed.
#### 2a. ENVIRONMENT.md Does Not Exist
Create a new ENVIRONMENT.md at the project root using the template structure below.
#### 2b. ENVIRONMENT.md Already Exists
Treat as append-only:
# <Environment Name>) and which service subsections (## <Service Name>) exist.TODO placeholder values.#### 2c. ENVIRONMENT.md Template
# Context
- This document contains environment-specific variables and credentials for all 3rd party
supporting applications used in this project.
- Organized by environment as defined in CLAUDE.md.
- **This file must NOT be committed to version control.**
---
# {{Environment Name}}
{{For localhost:}}
- Kube Config: `{{path to kube config or TODO}}`
{{For remote environments:}}
- SSH Credentials:
- Username: `{{username or TODO}}`
- Password: `{{password or TODO}}`
- Kube Config: `{{path to kube config or TODO}}`
## {{3rd Party Application Name}}
- {{Technology}} version {{version}}
{{Technology-specific fields — see Section 2d}}
---#### 2d. Technology-Specific Config Fields
For each 3rd party application, include config fields based on its technology type. Use credential rules from CLAUDE.md # Rules section for default username/password values. Use TODO for any value not yet known.
| Technology | Config Fields |
|---|---|
| MongoDB | Host, Port, Username, Password, Databases (list) |
| MySQL | Host, Port, Username, Password, Databases (list) |
| Redis | Host, Port, Password, Database Index |
| RabbitMQ | Host, AMQP Port, Admin Port, Username, Password, Vhost |
| Keycloak | Host, HTTP Port, Admin Username, Admin Password, Realm, Client IDs |
| Meilisearch | Host, Port, Master Key |
| Kong | Proxy Host, Proxy Port, Admin Host, Admin Port |
| Mailcatcher | SMTP Host, SMTP Port, HTTP Port |
#### 2e. Custom Docker Image Override
Any service in ENVIRONMENT.md may optionally specify a custom Docker image using the Docker Image field:
Format: - Docker Image: <image-reference> Example: - Docker Image: gilacode/hub_single_sign_on:26.5.4 The image will be used as-is in the K8s manifest with imagePullPolicy: IfNotPresent.
When the Docker Image field is not present, the skill falls back to the official Docker Hub image with the exact version from CLAUDE.md (default behavior).
This field is per-environment in ENVIRONMENT.md — one environment may use a custom image while another uses the official image. The skill reads the target environment's section.
Default values:
- Domain: field in CLAUDE.md (e.g., localhost, home.server). If no Domain is specified, fall back to localhost for localhost environments or the SSH IP for remote environments. If neither is available, use TODO.27017, MySQL: 3306, Redis: 6379, RabbitMQ AMQP: 5672, RabbitMQ Admin: 15672, Keycloak: 8180, Meilisearch: 7700, Kong Proxy: 8000, Kong Admin: 8001, Mailcatcher SMTP: 1025, Mailcatcher HTTP: 1080)bestrnd / B3st1n3t@2025), or technology defaults (e.g., RabbitMQ: guest/guest, MongoDB: no auth)#### 3a. Ensure Folder Structure
environment/ folder exists at the project root. If not, create it.Resulting structure (all manifests directly in environment/):
environment/
namespace.yaml
smtp_server.yaml
hub_cache_pvc.yaml
hub_cache.yaml
hub_core_database_pvc.yaml
hub_core_database.yaml
...#### 3b. Generate Namespace Manifest
Create environment/namespace.yaml:
urp)#### 3c. Generate PVC Manifests (Separate Files)
For each 3rd party application that requires data persistence (databases, message queues, caches), generate a separate PVC file: environment/<service_snake_case>_pvc.yaml.
Why separate files: If the PVC is bundled inside the service manifest, running kubectl delete -f <service>.yaml followed by kubectl apply -f <service>.yaml would delete and recreate the PVC, destroying all persisted data. Keeping the PVC in its own file ensures that kubectl delete -f <service>.yaml only removes the StatefulSet, ConfigMap, Secret, and Services — the PVC (and its data) remains untouched.
The PVC file contains only the PersistentVolumeClaim resource:
# ==============================================================================
# {{Application Name}} ({{Technology}}) — PersistentVolumeClaim
# ==============================================================================
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{service-name}}-pvc
namespace: {{namespace}}
labels:
app: {{service-name}}
project: {{project-code}}
environment: {{environment}}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{size — see Section 3d for defaults per technology}}#### 3d-svc. Generate Per-Service Manifests
For each 3rd party application, generate environment/<service_snake_case>.yaml containing a multi-document YAML (separated by ---) with:
Docker Image is specified → use the exact image reference as-is. Set imagePullPolicy: IfNotPresent. Do NOT include args or command — the custom image's ENTRYPOINT/CMD handles startup.mongo:7.0.6, mysql:8.4). Include args/command as needed by the technology.volumeMounts referencing the PVC (defined in the separate _pvc.yaml file) for data persistenceenv or envFrom referencing ConfigMap and SecretserviceName matching the headless Service nameclusterIP: None) — for StatefulSet stable DNSUse a deterministic NodePort assignment strategy to avoid conflicts:
30000 + (index * 10) where index is the service's position in alphabetical orderImportant: The service manifest must NOT contain the PersistentVolumeClaim. It only references the PVC by claimName in the StatefulSet's volumes section.
#### 3d. Technology-Specific Manifest Details
MongoDB:
mongo:{version}MONGO_INITDB_ROOT_USERNAME, MONGO_INITDB_ROOT_PASSWORD (from Secret, or skip if no auth)mongosh --eval "db.adminCommand('ping')"MySQL:
mysql:{version}MYSQL_ROOT_PASSWORD (from Secret)/docker-entrypoint-initdb.d/ scriptmysqladmin ping -h localhostRedis:
redis:{version}REDIS_PASSWORD (from Secret, optional — skip if no auth)redis-cli pingRabbitMQ:
rabbitmq:{version}-management (include management plugin for admin UI)RABBITMQ_DEFAULT_USER, RABBITMQ_DEFAULT_PASS, RABBITMQ_DEFAULT_VHOST (from Secret/ConfigMap)rabbitmq-diagnostics -q pingKeycloak:
Docker Image first (see Section 2e).gilacode/hub_single_sign_on:26.5.4): use the specified image name; do NOT add args: ["start-dev"] (custom image handles startup). Use HTTP Port from ENVIRONMENT.md (typically 8180 for custom builds) for containerPort, probes, and services. Add KC_HTTP_PORT to ConfigMap.quay.io/keycloak/keycloak:{version} with args: ["start-dev"]. Default port 8080.KC_DB, KC_DB_URL, KC_DB_USERNAME, KC_DB_PASSWORD, KC_HEALTH_ENABLED, KC_HTTP_ENABLED, KC_HOSTNAME_STRICT, KC_HTTP_PORT, KEYCLOAK_ADMIN, KEYCLOAK_ADMIN_PASSWORD (from Secret/ConfigMap)/health/ready on the configured HTTP portKong API Gateway:
kong:{version}KONG_DATABASE=off, KONG_PROXY_LISTEN=0.0.0.0:8000, KONG_ADMIN_LISTEN=0.0.0.0:8001/status on admin portMailcatcher (SMTP):
schickling/mailcatcher:{version} or sj26/mailcatcher:latest (if specific version unavailable)Meilisearch:
getmeili/meilisearch:v{version}MEILI_MASTER_KEY (from Secret)/health#### 3e. Create or Update Logic
For each service, there are up to two files to manage in environment/:
<service_snake_case>_pvc.yaml — PVC file (only for services that require persistence)<service_snake_case>.yaml — service manifest (ConfigMap, Secret, StatefulSet, Services)For each file:
_pvc.yaml only)# CUSTOM: comments#### 3f. Remote Accessibility
All NodePort Services must be accessible from the developer's machine using the CLI tools specified in DEVTOOL.md. Include a comment block at the top of each service manifest with connection instructions:
# Service: {{Application Name}} ({{Technology}} {{version}})
# Environment: {{Environment Name}}
#
# Connect from local machine:
# {{CLI tool from DEVTOOL.md}} {{connection command using NodePort}}
#
# Example:
# mysql -h {{host}} -P {{nodeport}} -u {{username}} -p{{password}}
# mongosh mongodb://{{host}}:{{nodeport}}/{{database}}
# rdcli -h {{host}} -p {{nodeport}}
# rabbitmqadmin -H {{host}} -P {{nodeport}} list queues
---Use the Domain from the target environment's - Domain: field in CLAUDE.md as host with NodePort (e.g., localhost, home.server). If no Domain is specified, fall back to localhost for localhost environments or the SSH IP for remote environments.
Print a summary of all actions taken:
## K8s Environment Preparation Summary
### Target Environment
| Environment | Deployment Type | Output Folder |
|-------------|----------------|---------------|
| Home Server | Kubernetes | environment/ |
### ENVIRONMENT.md
| Action | Details |
|--------|---------|
| Created/Updated | Synced Home Server environment, 11 services |
### K8s Manifests Generated
| Service | File | Status |
|---------|------|--------|
| SMTP Server | environment/smtp_server.yaml | Created |
| Hub Cache (PVC) | environment/hub_cache_pvc.yaml | Created |
| Hub Cache | environment/hub_cache.yaml | Created |
| Hub Core Database (PVC) | environment/hub_core_database_pvc.yaml | Created |
| Hub Core Database | environment/hub_core_database.yaml | Created |
| ... | ... | ... |
### NodePort Assignments
| Service | Primary Port | NodePort |
|---------|-------------|----------|
| HC Adapter Message Queue | 5672 | 30000 |
| HC Database | 3306 | 30010 |
| Hub Cache | 6379 | 30020 |
| Hub Core Database | 27017 | 30030 |
| Hub Single Sign On | 8180 (custom) / 8080 (official) | 30040 |
| Hub Support Database | 3306 | 30050 |
| SC API Gateway | 8000 | 30060 |
| SC Adapter Message Queue | 5672 | 30070 |
| SC Database | 3306 | 30080 |
| SMTP Server | 1025 | 30090 |<service>_pvc.yaml files, never bundled inside the service manifest. This prevents accidental data loss when recreating services with kubectl delete -f / kubectl apply -f. The service manifest references the PVC by claimName only.Docker Image field first (see Section 2e). If present, use the exact image reference with imagePullPolicy: IfNotPresent and do not add args/command. If absent, fall back to the official Docker Hub image with the exact version from CLAUDE.md (never use latest).# Rules section in CLAUDE.md for standard username/password format.# CUSTOM: are preserved.TODO in ENVIRONMENT.md, use TODO (base64-encoded) in the Secret and log a warning.depgen-k8s).~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.