harbor skills
v1.0.0Harbor 镜像仓库综合管理技能。用于 Harbor 日常运维、项目与镜像管理、安全扫描、清理策略、CI/CD 集成、GitOps、复制规则、存储管理、备份恢复、webhook 联动等所有 Harbor 相关操作。当用户提到 Harbor、镜像仓库管理、Docker 镜像、镜像安全扫描、CI/CD 镜像推送/拉...
Security Scan
Capability signals
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
OpenClaw
Suspicious
medium confidencePurpose & Capability
Skill name/description (Harbor management) aligns with included scripts and reference docs: cleanup, compliance, robot account management, backup/restore, GitOps integration. However the documentation and examples use multiple different environment variable names (HARBOR_USERNAME/HARBOR_PASSWORD vs HARBOR_USER/HARBOR_PASS vs HARBOR_AUTH), and examples reference host tools (docker, pg_dump, rclone) that are not declared in the metadata. These inconsistencies reduce confidence that the declared requirements match what the skill actually needs.
Instruction Scope
SKILL.md and scripts instruct the agent to call Harbor APIs with admin credentials and to run local administrative actions (curl, python scripts, docker exec pg_dump, rclone copy, docker-compose). Those actions are pertinent to Harbor ops, but the instructions reference specific filesystem paths (e.g., /root/.openclaw/workspace/skills/harbor-manager/scripts/..., /data/harbor-backup) and require access to host tooling and backup destinations. The docs also show inconsistent env var names and examples that could cause accidental use of wrong variables. No instructions direct data to unknown external endpoints besides the backup target (S3 via rclone) or Harbor itself.
Install Mechanism
No install spec (instruction-only with bundled scripts). That keeps install risk low since nothing is automatically downloaded or executed at install time. The skill does include Python scripts that will run if invoked, but there is no remote fetch or archive extraction in the registry metadata.
Credentials
Registry metadata declares no required env vars or credentials, yet SKILL.md and scripts clearly expect sensitive credentials (Harbor admin username/password or token via HARBOR_USERNAME/HARBOR_PASSWORD, HARBOR_USER/HARBOR_PASS, HARBOR_AUTH, HARBOR_TOKEN, etc.). The skill also expects access to host tools (docker, pg_dump, rclone) and backup storage credentials (S3) in examples but does not declare those needs. The multiplicity and inconsistency of credential/environment names is a red flag: it increases chance of accidental credential exposure or misconfiguration because the skill will read different env vars in different places.
Persistence & Privilege
Skill is user-invocable, not always:true, and allows autonomous invocation (default). It does not request to modify other skills or global agent settings. The ability to perform privileged Harbor admin actions depends on credentials you supply at runtime; that is expected for an admin tool.
What to consider before installing
This skill appears to be a legitimate Harbor admin toolkit, but several inconsistencies and omissions mean you should inspect and control usage before installing:
- Verify and standardize credentials: SKILL.md and the scripts use multiple env var names (HARBOR_USERNAME/HARBOR_PASSWORD, HARBOR_USER/HARBOR_PASS, HARBOR_AUTH, HARBOR_TOKEN). Decide which env vars you will supply and ensure the agent/runtime will not inadvertently expose other secrets.
- Expect host-level operations: backup examples and some instructions invoke docker exec, pg_dump, docker-compose, rclone and reference host paths (/data/harbor-backup, /opt/harbor). Only grant the skill access to those systems when you intend to run such operations; test in dry-run mode first.
- Test in non-prod and dry-run: cleanup_dryrun.py supports dry-run — use that before any destructive action. The scripts include interactive confirmations for deletions, but double-check before allowing non-interactive agent runs.
- Review the bundled scripts locally: although there are no remote downloads, the Python scripts will execute network and filesystem actions; review them for bugs and for which exact env vars they read (there are some coding issues and inconsistent imports in the provided sources).
- Provide least-privilege credentials: if you must give credentials, prefer a scoped robot token with minimal rights and an expiry rather than a long-lived admin password.
- Additional info that would change this assessment: an official publisher/homepage or corrected metadata that declares required env vars and required system binaries (docker, pg_dump, rclone, python3) would increase confidence. Conversely, a request by the skill to persist credentials or to run automatically on every agent run (always:true) combined with these env inconsistencies would raise more serious concern.Like a lobster shell, security has layers — review code before you run it.
harbor-skillslatest
Harbor Manager
Harbor 是企业级容器镜像仓库(CNCF 毕业项目)。
环境准备
首次使用需要配置连接信息,优先使用环境变量(可在 TOOLS.md 中预填):
| 变量 | 说明 | 示例 |
|---|---|---|
HARBOR_URL | Harbor 地址(不含 /) | https://harbor.mycompany.com |
HARBOR_USERNAME | 管理员账号 | admin |
HARBOR_PASSWORD | 密码或 API Token | Harbor12345 |
或通过对话传入。Token 优先(比密码更安全)。
快速诊断
# 检查 Harbor 健康状态
curl -s -u "$HARBOR_USER:$HARBOR_PASS" "$HARBOR_URL/api/v2.0/health" | jq .
# 列出所有项目(Python)
python3 -c "
import requests, os
r = requests.get(f'{os.environ[\"HARBOR_URL\"]}/api/v2.0/projects',
headers={'Authorization': f'Basic {os.environ[\"HARBOR_AUTH\"]}'})
print(r.json())
"
项目管理
创建项目
curl -X POST "$HARBOR_URL/api/v2.0/projects" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{
"project_name": "my-app",
"public": false,
"metadata": {"description": "业务镜像仓库", "storage_quota": "500G"}
}'
修改存储配额(Python)
# refs: references/harbor-api.md
import requests, base64, os
auth = base64.b64encode(f"{u}:{p}".encode()).decode()
headers = {"Authorization": f"Basic {auth}", "Content-Type": "application/json"}
# 查找项目ID
proj = requests.get(f"{url}/api/v2.0/projects", params={"name": "my-app"}, headers=headers).json()[0]
pid = proj["project_id"]
# 更新配额(单位:bytes,500G = 500*1024^3)
requests.put(f"{url}/api/v2.0/projects/{pid}",
headers=headers, json={"metadata": {"storage_quota": str(500*1024**3)}})
print(f"项目 {pid} 配额已更新为 500G")
镜像管理
列出镜像
# 按项目列出所有镜像
curl "$HARBOR_URL/api/v2.0/projects/my-app/repositories" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '.[].name'
# 查看某镜像的所有标签
curl "$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/tags" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '.[].name'
# 镜像详情(含大小、扫描状态)
curl "$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/artifacts?with_tag=true&with_scan_overview=true" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '.[].{tags: .tag, size: .size, scan: .scan_summary}'
删除镜像(按标签)
# 删除指定标签(保留其他标签)
curl -X DELETE \
"$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/tags/v1.2.3" \
-u "$HARBOR_USER:$HARBOR_PASS"
# 批量删除(用 jq 生成)
TAGS=$(curl -s "$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/tags" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq -r '.[].name | select(startswith("v0"))')
for tag in $TAGS; do
echo "删除: $tag"
curl -X DELETE "$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/tags/$tag" \
-u "$HARBOR_USER:$HARBOR_PASS"
done
删除不留用的镜像(Python)
# refs: references/cleanup-policy.md
import requests, base64, os, datetime
def delete_artifact(project, repo, reference, dry_run=True):
url = f"{os.environ['HARBOR_URL']}/api/v2.0/projects/{project}/repositories/{repo}/artifacts/{reference}"
if dry_run:
print(f"[演练] 应删除: {url}")
else:
r = requests.delete(url, headers=auth_header)
print(f"[已删除] {reference}" if r.status_code == 200 else f"[失败] {r.status_code}")
注意:Harbor GC 需要手动触发,删除后运行垃圾回收。
清理策略
配置保留策略
策略规则在 references/cleanup-policy.md 中有详细说明。
典型场景:
| 场景 | 规则 |
|---|---|
| 保留最近 N 个版本 | kept_tags >= N(按 push 时间排序) |
| 删除 N 天前镜像 | pushed_time < now - N days |
| 保留带有特定前缀的标签 | tag =~ ^release- |
| 清理快照版本 | tag =~ ^snap- |
演练模式(评估影响)
python3 /root/.openclaw/workspace/skills/harbor-manager/scripts/cleanup_dryrun.py \
--project my-app --repo my-app--api --policy "保留最近5个" --url "$HARBOR_URL"
清理策略推荐 YAML 格式
# 清理策略示例(用于自动化脚本生成)
project: my-app
repo: my-app--api
rules:
- action: delete
condition: tag not in recent(5)
exclude:
tags: ["latest", "stable", "release-*"]
- action: delete
condition: pushed_time < days_ago(30)
exclude:
tags: ["latest"]
垃圾回收(GC)
# 1. 触发 GC(拉取管理员 credentials)
curl -X POST "$HARBOR_URL/api/v2.0/system/gc/schedule" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{"schedule":{"type":"manual"}}'
# 2. 查看 GC 状态
curl "$HARBOR_URL/api/v2.0/system/gc" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '.[] | {id: .id, status: .job_status, start: .start_time}'
# 3. GC 完成后清理孤儿 Blob(自动执行,也可手动触发)
curl -X POST "$HARBOR_URL/api/v2.0/system/gc/schedule" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{"schedule":{"type":"none"}, "dry_run": false}'
⚠️ GC 期间 Harbor 会进入维护模式,建议在低峰期执行。
存储使用情况
# 查看项目存储使用
curl "$HARBOR_URL/api/v2.0/projects/my-app" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '{name: .name, storage: .metadata.storage_quota, used: .metadata.storage_quota_used}'
# 查看系统总体存储
curl "$HARBOR_URL/api/v2.0/statistics" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '{total: .total_storage, used: .used_storage, free: .free_storage}'
复制管理
创建复制规则
curl -X POST "$HARBOR_URL/api/v2.0/replication/policies" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{
"name": "backup-to-dr-site",
"src_registry": {"id": 1, "name": "local"},
"dest_registry": {"id": 2, "name": "dr-harbor"},
"filters": [
{"type": "name", "value": "my-app/.*"},
{"type": "tag", "value": ".*"}
],
"trigger": {"type": "scheduled", "trigger_settings": {"cron": "0 2 * * * *"}},
"deletion": true,
"override": true
}'
触发立即执行
curl -X POST "$HARBOR_URL/api/v2.0/replication/executions" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{"policy_id": 3}'
# 查看执行状态
curl "$HARBOR_URL/api/v2.0/replication/executions?policy_id=3" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '.[] | {id: .id, status: .status, summary: .status_ext}'
代理缓存(Proxy Cache)
创建代理缓存项目
curl -X POST "$HARBOR_URL/api/v2.0/projects" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{
"project_name": "proxy-cache-dockerhub",
"public": false,
"metadata": {
"proxy_cache_name": "dockerhub",
"description": "Docker Hub 代理缓存"
}
}'
使用代理缓存拉取镜像
# Pod 层面配置代理(通过 /etc/docker/daemon.json)
{
"registry-mirrors": ["https://proxy-cache-dockerhub.harbor.mycompany.com"]
}
# 或手动拉取
docker pull proxy-cache-dockerhub.library/nginx:latest
漏洞扫描
触发全量扫描
# 扫描单个镜像
curl -X POST \
"$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/artifacts/sha256:abc123.../scan" \
-u "$HARBOR_USER:$HARBOR_PASS"
# 扫描整个项目所有镜像
curl -X POST \
"$HARBOR_URL/api/v2.0/projects/my-app/scanAll" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{"selector":"all"}'
获取扫描报告
# 获取镜像扫描摘要
curl "$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/artifacts/v1.2.3?with_scan_summary=true" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '{scan: .scan_summary}'
# 导出详细扫描报告(CSV格式)
curl "$HARBOR_URL/api/v2.0/projects/my-app/repositories/my-app--api/artifacts/v1.2.3/scan_report?accept=text/csv" \
-u "$HARBOR_USER:$HARBOR_PASS"
自动扫描策略
# 设置自动化扫描:镜像推送后自动触发扫描
curl -X PUT "$HARBOR_URL/api/v2.0/projects/my-app" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{"auto_scan": true}'
镜像签名(Notary)
# 1. 启用 Notary(需在 Harbor 部署时配置)
# 2. 对镜像签名(需安装 docker content trust 相关工具)
DOCKER_CONTENT_TRUST=1
DOCKER_CONTENT_TRUST_SERVER="$HARBOR_URL"
docker pull my-app/my-app--api:v1.2.3
docker tag my-app/my-app--api:v1.2.3 harbor.mycompany.com/my-app/my-app--api:v1.2.3
docker push harbor.mycompany.com/my-app/my-app--api:v1.2.3
# 3. 验证签名
DOCKER_CONTENT_TRUST=1
docker pull harbor.mycompany.com/my-app/my-app--api:v1.2.3
机器人账号(Robot Account)
创建项目机器人账号
curl -X POST "$HARBOR_URL/api/v2.0/projects/my-app/robots" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-pipeline",
"description": "CI/CD流水线使用",
"access": [
{"resource": "/project/my-app/repository", "action": "push"},
{"resource": "/project/my-app/repository", "action": "pull"}
],
"expires_at": 0 # 永不过期
}'
CI 使用机器人账号
# 获取机器人 token(创建时返回的 credentials.secret)
docker login "$HARBOR_URL" -u "robot$my-app$ci-pipeline" -p "$ROBOT_TOKEN"
# Jenkinsfile / GitLab CI 示例
environment:
DOCKER_AUTH:
script: |
TOKEN=$(curl -s -u "robot\$my-app\$ci-pipeline:$ROBOT_SECRET" \
"$HARBOR_URL/api/v2.0/robots/1/token" | jq -r '.token')
echo $TOKEN | docker login -u "robot\$my-app\$ci-pipeline" --password-stdin "$HARBOR_URL"
RBAC 权限管理
# 添加项目成员
curl -X POST "$HARBOR_URL/api/v2.0/projects/my-app/members" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{"member_user": {"username": "dev-user"}, "role_id": 2}' # 2=开发者
# 角色ID说明:1=项目管理员, 2=开发者, 3=访客, 4=维护者
Webhook
创建 Webhook
curl -X POST "$HARBOR_URL/api/v2.0/projects/my-app/webhook" \
-u "$HARBOR_USER:$HARBOR_PASS" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-trigger",
"targets": [{
"type": "http",
"address": "https://ci.mycompany.com/webhook/harbor",
"skip_cert_verify": true,
"auth_header": "Bearer xxxxx"
}],
"event_types": ["SCANNING_COMPLETED", "PUSH_ARTIFACT", "DELETE_ARTIFACT"]
}'
Webhook payload 示例:
{
"type": "PUSH_ARTIFACT",
"occur_at": 1700000000,
"artifact": {
"media_type": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:abc123",
"tags": ["v1.2.3"]
},
"project": {"id": 1, "name": "my-app"},
"repository": {"name": "my-app--api"}
}
审计日志
# 查看项目审计日志
curl "$HARBOR_URL/api/v2.0/projects/my-app/logs?page=1&page_size=20" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq '.'
# 导出为 CSV
curl "$HARBOR_URL/api/v2.0/projects/my-app/logs?page=1&page_size=100&sort=op_time_desc" \
-u "$HARBOR_USER:$HARBOR_PASS" | jq -r '.[] | [.op_time, .username, .resource, .operation] | @csv'
备份与恢复
备份(Harbor 数据)
# 备份清单(推荐 cron 定期执行)
# refs: references/backup-recovery.md
BACKUP_DIR="/data/harbor-backup"
DATE=$(date +%Y%m%d_%H%M%S)
# 1. 备份数据库
docker exec -t harbor-db pg_dump -U postgres registry > "$BACKUP_DIR/harbor-db-$DATE.sql"
# 2. 备份核心配置(shared volume)
tar czf "$BACKUP_DIR/harbor-config-$DATE.tar.gz" \
/data/harbor/redis /data/harbor/registry /data/harbor/trivy-adapter
# 3. 上传至对象存储
# rclone sync "$BACKUP_DIR/" "s3:my-bucket/harbor-backups/"
echo "备份完成: $DATE"
恢复
# 1. 停止 Harbor
cd /opt/harbor && docker-compose down
# 2. 恢复数据库
docker exec -i harbor-db psql -U postgres registry < "$BACKUP_DIR/harbor-db-$DATE.sql"
# 3. 恢复配置文件
tar xzf "$BACKUP_DIR/harbor-config-$DATE.tar.gz" -C /
# 4. 重启 Harbor
docker-compose up -d
合规性检查
# 等保 2.0 / GDPR 检查项(详见 references/compliance.md)
# 自动化检查脚本:
python3 /root/.openclaw/workspace/skills/harbor-manager/scripts/compliance_check.py \
--harbor-url "$HARBOR_URL" --auth "$HARBOR_USER:$HARBOR_PASS" \
--standard " 等保2级" --output /tmp/harbor-compliance-report.html
检查项包括:
- ✅ 匿名访问是否关闭
- ✅ Robot Account 是否有过期设置
- ✅ 镜像扫描覆盖率
- ✅ CVE 漏洞是否在可接受阈值内
- ✅ 审计日志保留时长
- ✅ HTTPS 强制开启
- ✅ 密码策略配置
CI/CD 集成速查
| 工具 | 集成方式 |
|---|---|
| Jenkins | withCredentials([string(credentialsId: 'harbor', variable: 'HARBOR_TOKEN')]) + docker login |
| GitLab CI | image: docker:latest + before_script 登录 |
| GitHub Actions | uses: docker/login-action@v3 |
| Argo CD | Application YAML 中引用 Image Updater 或使用 Argo CD Image Updater |
| Tekton | Task 中用 dockerauth secret 登录后 docker push |
GitOps 配置管理
参考 references/gitops.md 了解更多 GitOps 工具与 Harbor 的集成方式。
参考文档
| 文件 | 内容 |
|---|---|
references/harbor-api.md | 完整 Harbor API v2.0 参考(认证、请求格式、错误码) |
references/cleanup-policy.md | 镜像清理策略详细规则与演练脚本 |
references/webhook.md | Webhook 事件类型与 payload 格式说明 |
references/backup-recovery.md | 备份恢复详细步骤与灾难恢复预案 |
references/gitops.md | GitOps 集成(Argo CD / Flux / Helm) |
references/compliance.md | 等保2.0 / GDPR 合规检查项说明 |
scripts/cleanup_dryrun.py | 清理演练脚本 |
scripts/compliance_check.py | 合规性检查脚本 |
scripts/robot_account.py | 机器人账号创建与轮换脚本 |
Comments
Loading comments...
