[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6P9PE4TPPZFW2JYDMHQ95AD":3,"skill-same:01M6P9PE4TPPZFW2JYDMHQ95AD":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":25,"commitSha":52,"skillDirectory":53,"forksCount":13,"repositoryHtmlUrl":54,"repositoryHomepageUrl":6,"ownerHtmlUrl":55,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":56,"install":57,"resources":70},"01M6P9PE4TPPZFW2JYDMHQ95AD","model-supply-chain-security",null,"Secure the AI model supply chain with artifact signing, provenance attestation, SBOM workflows, dependency controls, and trusted model promotion.","duc-duy-1612\u002FOnline-Delivery-Systems-Web","duc-duy-1612","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F192231384?v=4","01M6NSDKQQDKVTHZ8DZMZ1VYY6","01M6NSDKW8DDVTQHBT1HBDDJPT",0,"MIT","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fmodel-supply-chain-security\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"model supply chain security","supply chain security","supply","model","chain","security","supply chain","main","relevant","scripts","scope","active","artifact","community","dependency","only","devops-security","attestation","assessment","workflows","2026-11-10 10:12:30",false,"---\nname: model-supply-chain-security\ndescription: Secure the AI model supply chain with artifact signing, provenance attestation,\n  SBOM workflows, dependency controls, and trusted model promotion.\ncategory: security\nrisk: safe\nsource: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\nsource_repo: BagelHole\u002FDevOps-Security-Agent-Skills\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Requires the relevant security tooling (scanners, vault CLIs) and an\n  authorized scope for any active assessment. Docs-only; helper scripts and templates\n  not bundled.\nmetadata:\n  author: devops-skills\n  version: '1.0'\n---\n\n# Model Supply Chain Security\n\nProtect models and inference components from tampering, dependency compromise, and untrusted artifact promotion.\n\n## When to Use This Skill\n\nUse this skill when:\n- Pulling pretrained models from public registries (Hugging Face, TensorFlow Hub)\n- Building model-serving containers for production deployment\n- Establishing trust policies for ML artifact promotion across environments\n- Responding to supply chain incidents affecting ML dependencies\n- Meeting SLSA or SOC2 compliance requirements for AI systems\n\n## Prerequisites\n\n- `cosign` v2+ installed for signing and verification\n- `syft` for SBOM generation of model-serving images\n- `crane` or `skopeo` for OCI image inspection\n- Container registry with signature support (GHCR, ECR, ACR, Artifact Registry)\n- CI\u002FCD pipeline with provenance generation capability\n\n## Threats\n\n- Poisoned pretrained weights or adapters\n- Malicious model conversion tools or loaders\n- Compromised build pipelines and registries\n- Insecure runtime images with critical CVEs\n- Typosquatting on model registries\n- Deserialization attacks via pickle or custom loaders\n\n## Control Objectives\n\n- Verify artifact integrity end-to-end\n- Prove provenance for every promoted model\n- Detect vulnerable dependencies before deploy\n- Restrict execution to trusted signed artifacts\n\n## Model Signing with Cosign\n\n### Sign a Model Artifact\n\n```bash\n# Generate a keypair (store private key securely)\ncosign generate-key-pair\n\n# Sign an OCI-packaged model image\ncosign sign --key cosign.key ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n\n# Keyless signing with Sigstore (uses OIDC identity)\ncosign sign ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n\n# Verify the signature\ncosign verify --key cosign.pub ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n\n# Keyless verification (requires certificate identity)\ncosign verify \\\n  --certificate-identity=ci-bot@acme.iam.gserviceaccount.com \\\n  --certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com \\\n  ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n```\n\n### Sign Model Weight Files Directly\n\n```bash\n# For model files stored as blobs (not OCI images)\n# Compute digest and sign\nsha256sum model-weights.safetensors > model-weights.sha256\ncosign sign-blob --key cosign.key model-weights.safetensors \\\n  --output-signature model-weights.sig \\\n  --output-certificate model-weights.crt\n\n# Verify blob signature\ncosign verify-blob --key cosign.pub \\\n  --signature model-weights.sig \\\n  model-weights.safetensors\n```\n\n## SLSA for ML Pipelines\n\n### SLSA Level Requirements for Model Builds\n\n```yaml\n# slsa-requirements.yaml\nslsa_levels:\n  level_1:\n    - Build process is scripted (not manual)\n    - Provenance document generated automatically\n  level_2:\n    - Build runs on hosted CI service\n    - Provenance is authenticated (signed)\n    - Source is version controlled\n  level_3:\n    - Build environment is ephemeral and isolated\n    - Provenance is non-falsifiable (hardened builder)\n    - Source integrity verified (two-person review)\n```\n\n### Generate SLSA Provenance for Model Training\n\n```yaml\n# .github\u002Fworkflows\u002Fmodel-build-slsa.yml\nname: Model Build with SLSA Provenance\non:\n  push:\n    tags: ['model-v*']\n\njobs:\n  train-and-package:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n      contents: read\n      packages: write\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Train model\n        run: python train.py --config configs\u002Fproduction.yaml\n\n      - name: Package model as OCI artifact\n        run: |\n          oras push ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:${{ github.ref_name }} \\\n            model-weights.safetensors:application\u002Fvnd.acme.model.safetensors \\\n            model-config.json:application\u002Fjson\n\n      - name: Generate SBOM for training environment\n        run: |\n          syft dir:. -o cyclonedx-json > training-sbom.json\n\n      - name: Sign and attest\n        run: |\n          cosign sign ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:${{ github.ref_name }}\n          cosign attest --predicate training-sbom.json \\\n            --type cyclonedx \\\n            ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:${{ github.ref_name }}\n\n      - name: Generate provenance\n        uses: slsa-framework\u002Fslsa-github-generator\u002F.github\u002Fworkflows\u002Fgenerator_container_slsa3.yml@v2.0.0\n        with:\n          image: ghcr.io\u002Facme\u002Fml-models\u002Fsentiment\n          digest: ${{ steps.push.outputs.digest }}\n```\n\n## Model Cards for Provenance\n\n```yaml\n# model-card.yaml\nmodel_details:\n  name: \"sentiment-classifier-v2.1.0\"\n  version: \"2.1.0\"\n  type: \"text-classification\"\n  framework: \"pytorch\"\n  license: \"Apache-2.0\"\n\nprovenance:\n  training_data:\n    source: \"s3:\u002F\u002Facme-datasets\u002Fsentiment-v3\u002F\"\n    hash: \"sha256:abc123...\"\n    data_card_ref: \"https:\u002F\u002Finternal.acme.com\u002Fdata-cards\u002Fsentiment-v3\"\n  training_config:\n    source: \"git:\u002F\u002Fgithub.com\u002Facme\u002Fml-models@abc123\"\n    hyperparameters:\n      learning_rate: 0.00005\n      epochs: 10\n      batch_size: 32\n  build_environment:\n    builder: \"github-actions\"\n    runner: \"ubuntu-22.04\"\n    python: \"3.11.7\"\n    torch: \"2.1.2\"\n    cuda: \"12.1\"\n  build_id: \"gh-actions-12345\"\n  commit_sha: \"abc123def456\"\n  build_timestamp: \"2025-01-15T10:30:00Z\"\n  signed_by: \"ci-bot@acme.iam.gserviceaccount.com\"\n\nperformance:\n  accuracy: 0.94\n  f1_score: 0.93\n  evaluation_dataset: \"s3:\u002F\u002Facme-datasets\u002Fsentiment-eval-v3\u002F\"\n  evaluation_hash: \"sha256:def456...\"\n\nsecurity:\n  vulnerability_scan: \"clean\"\n  sbom_ref: \"ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0.sbom\"\n  last_security_review: \"2025-01-10\"\n  known_limitations:\n    - \"May produce biased outputs for underrepresented languages\"\n    - \"Not evaluated for adversarial robustness\"\n```\n\n## Registry Scanning\n\n```bash\n# Scan model-serving image for CVEs\ntrivy image ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:v2.1.0\n\n# Generate SBOM for the serving container\nsyft ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:v2.1.0 -o spdx-json > serving-sbom.json\n\n# Scan SBOM for vulnerabilities\ngrype sbom:serving-sbom.json --fail-on critical\n\n# Check for known-malicious model files (pickle scanning)\npip install fickling\nfickling --check model.pkl\n```\n\n### Automated Registry Scan Pipeline\n\n```yaml\n# .github\u002Fworkflows\u002Fregistry-scan.yml\nname: Nightly Registry Scan\non:\n  schedule:\n    - cron: '0 2 * * *'\n\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        image:\n          - ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:latest\n          - ghcr.io\u002Facme\u002Fml-models\u002Fembedding-serving:latest\n          - ghcr.io\u002Facme\u002Fml-models\u002Frag-api:latest\n    steps:\n      - name: Scan image\n        run: |\n          trivy image --severity CRITICAL,HIGH \\\n            --exit-code 1 \\\n            --format json \\\n            --output scan-$(echo ${{ matrix.image }} | tr '\u002F:' '-').json \\\n            ${{ matrix.image }}\n\n      - name: Verify signatures are still valid\n        run: |\n          cosign verify \\\n            --certificate-identity=ci-bot@acme.iam.gserviceaccount.com \\\n            --certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com \\\n            ${{ matrix.image }}\n```\n\n## Promotion Policy Enforcement\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"model_promotion_gate.py - Verify model meets all promotion criteria.\"\"\"\n\nimport subprocess\nimport json\nimport sys\n\ndef check_signature(image: str) -> bool:\n    result = subprocess.run(\n        [\"cosign\", \"verify\", \"--certificate-identity=ci-bot@acme.iam.gserviceaccount.com\",\n         \"--certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef check_vulnerabilities(image: str) -> bool:\n    result = subprocess.run(\n        [\"trivy\", \"image\", \"--severity\", \"CRITICAL\", \"--exit-code\", \"1\",\n         \"--quiet\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef check_sbom_exists(image: str) -> bool:\n    result = subprocess.run(\n        [\"cosign\", \"verify-attestation\", \"--type\", \"cyclonedx\",\n         \"--certificate-identity=ci-bot@acme.iam.gserviceaccount.com\",\n         \"--certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef check_model_card(image: str) -> bool:\n    result = subprocess.run(\n        [\"cosign\", \"verify-attestation\", \"--type\", \"custom\",\n         \"--certificate-identity=ci-bot@acme.iam.gserviceaccount.com\",\n         \"--certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef main():\n    image = sys.argv[1]\n    checks = {\n        \"signature_valid\": check_signature(image),\n        \"no_critical_cves\": check_vulnerabilities(image),\n        \"sbom_attached\": check_sbom_exists(image),\n        \"model_card_present\": check_model_card(image),\n    }\n    all_passed = all(checks.values())\n    for name, passed in checks.items():\n        status = \"PASS\" if passed else \"FAIL\"\n        print(f\"  [{status}] {name}\")\n    if not all_passed:\n        print(\"Promotion BLOCKED: not all checks passed.\")\n        sys.exit(1)\n    print(\"Promotion APPROVED: all checks passed.\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n## Runtime Hardening\n\n- Run inference containers as non-root.\n- Apply egress restrictions to prevent unauthorized downloads.\n- Mount model volumes read-only when possible.\n- Alert on unsigned artifact pull attempts.\n- Use `safetensors` format instead of pickle to prevent deserialization attacks.\n\n```yaml\n# kubernetes deployment hardening\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: model-serving\nspec:\n  template:\n    spec:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        fsGroup: 1000\n      containers:\n        - name: inference\n          image: ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:v2.1.0\n          securityContext:\n            readOnlyRootFilesystem: true\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop: [\"ALL\"]\n          volumeMounts:\n            - name: model-weights\n              mountPath: \u002Fmodels\n              readOnly: true\n          resources:\n            limits:\n              memory: \"4Gi\"\n              nvidia.com\u002Fgpu: \"1\"\n      volumes:\n        - name: model-weights\n          persistentVolumeClaim:\n            claimName: model-weights-pvc\n            readOnly: true\n```\n\n## Kyverno Policy for Admission Control\n\n```yaml\napiVersion: kyverno.io\u002Fv1\nkind: ClusterPolicy\nmetadata:\n  name: require-signed-model-images\nspec:\n  validationFailureAction: Enforce\n  rules:\n    - name: verify-model-image-signature\n      match:\n        any:\n          - resources:\n              kinds: [\"Pod\"]\n              namespaces: [\"ml-serving\"]\n      verifyImages:\n        - imageReferences: [\"ghcr.io\u002Facme\u002Fml-models\u002F*\"]\n          attestors:\n            - entries:\n                - keyless:\n                    subject: \"ci-bot@acme.iam.gserviceaccount.com\"\n                    issuer: \"https:\u002F\u002Faccounts.google.com\"\n```\n\n## Troubleshooting\n\n| Problem | Cause | Solution |\n|---------|-------|----------|\n| `cosign verify` fails with \"no matching signatures\" | Image was pushed without signing | Re-run the signing step; check CI pipeline logs |\n| Provenance attestation missing | SLSA generator not configured | Add slsa-github-generator to the build workflow |\n| Trivy reports CVEs in base image | Stale base image | Update `FROM` image in Dockerfile; rebuild and re-sign |\n| Pickle deserialization warning | Model saved in unsafe format | Convert to safetensors: `model.save_pretrained(\".\", safe_serialization=True)` |\n| Keyless verification fails | Wrong OIDC issuer or identity | Check `--certificate-identity` and `--certificate-oidc-issuer` flags |\n| Model card not found for artifact | Attestation not attached to digest | Attach with `cosign attest --predicate model-card.yaml --type custom IMAGE` |\n\n## Related Skills\n\n- sbom-supply-chain (`sbom-supply-chain`) - Generate SBOM and provenance evidence\n- container-hardening (`container-hardening`) - Harden runtime container posture\n- model-registry-governance (`model-registry-governance`) - Controlled lifecycle and approvals\n\n## Limitations\n\n- Apply guidance only within authorized scope; test destructive steps in non-production first.\n- Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\n# Read-only first: inventory before any active step.\nwhich \u003Ctool> && \u003Ctool> --help | head -n 20\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n","# Model Supply Chain Security\n\nProtect models and inference components from tampering, dependency compromise, and untrusted artifact promotion.\n\n## When to Use This Skill\n\nUse this skill when:\n- Pulling pretrained models from public registries (Hugging Face, TensorFlow Hub)\n- Building model-serving containers for production deployment\n- Establishing trust policies for ML artifact promotion across environments\n- Responding to supply chain incidents affecting ML dependencies\n- Meeting SLSA or SOC2 compliance requirements for AI systems\n\n## Prerequisites\n\n- `cosign` v2+ installed for signing and verification\n- `syft` for SBOM generation of model-serving images\n- `crane` or `skopeo` for OCI image inspection\n- Container registry with signature support (GHCR, ECR, ACR, Artifact Registry)\n- CI\u002FCD pipeline with provenance generation capability\n\n## Threats\n\n- Poisoned pretrained weights or adapters\n- Malicious model conversion tools or loaders\n- Compromised build pipelines and registries\n- Insecure runtime images with critical CVEs\n- Typosquatting on model registries\n- Deserialization attacks via pickle or custom loaders\n\n## Control Objectives\n\n- Verify artifact integrity end-to-end\n- Prove provenance for every promoted model\n- Detect vulnerable dependencies before deploy\n- Restrict execution to trusted signed artifacts\n\n## Model Signing with Cosign\n\n### Sign a Model Artifact\n\n```bash\n# Generate a keypair (store private key securely)\ncosign generate-key-pair\n\n# Sign an OCI-packaged model image\ncosign sign --key cosign.key ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n\n# Keyless signing with Sigstore (uses OIDC identity)\ncosign sign ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n\n# Verify the signature\ncosign verify --key cosign.pub ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n\n# Keyless verification (requires certificate identity)\ncosign verify \\\n  --certificate-identity=ci-bot@acme.iam.gserviceaccount.com \\\n  --certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com \\\n  ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0\n```\n\n### Sign Model Weight Files Directly\n\n```bash\n# For model files stored as blobs (not OCI images)\n# Compute digest and sign\nsha256sum model-weights.safetensors > model-weights.sha256\ncosign sign-blob --key cosign.key model-weights.safetensors \\\n  --output-signature model-weights.sig \\\n  --output-certificate model-weights.crt\n\n# Verify blob signature\ncosign verify-blob --key cosign.pub \\\n  --signature model-weights.sig \\\n  model-weights.safetensors\n```\n\n## SLSA for ML Pipelines\n\n### SLSA Level Requirements for Model Builds\n\n```yaml\n# slsa-requirements.yaml\nslsa_levels:\n  level_1:\n    - Build process is scripted (not manual)\n    - Provenance document generated automatically\n  level_2:\n    - Build runs on hosted CI service\n    - Provenance is authenticated (signed)\n    - Source is version controlled\n  level_3:\n    - Build environment is ephemeral and isolated\n    - Provenance is non-falsifiable (hardened builder)\n    - Source integrity verified (two-person review)\n```\n\n### Generate SLSA Provenance for Model Training\n\n```yaml\n# .github\u002Fworkflows\u002Fmodel-build-slsa.yml\nname: Model Build with SLSA Provenance\non:\n  push:\n    tags: ['model-v*']\n\njobs:\n  train-and-package:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n      contents: read\n      packages: write\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Train model\n        run: python train.py --config configs\u002Fproduction.yaml\n\n      - name: Package model as OCI artifact\n        run: |\n          oras push ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:${{ github.ref_name }} \\\n            model-weights.safetensors:application\u002Fvnd.acme.model.safetensors \\\n            model-config.json:application\u002Fjson\n\n      - name: Generate SBOM for training environment\n        run: |\n          syft dir:. -o cyclonedx-json > training-sbom.json\n\n      - name: Sign and attest\n        run: |\n          cosign sign ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:${{ github.ref_name }}\n          cosign attest --predicate training-sbom.json \\\n            --type cyclonedx \\\n            ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:${{ github.ref_name }}\n\n      - name: Generate provenance\n        uses: slsa-framework\u002Fslsa-github-generator\u002F.github\u002Fworkflows\u002Fgenerator_container_slsa3.yml@v2.0.0\n        with:\n          image: ghcr.io\u002Facme\u002Fml-models\u002Fsentiment\n          digest: ${{ steps.push.outputs.digest }}\n```\n\n## Model Cards for Provenance\n\n```yaml\n# model-card.yaml\nmodel_details:\n  name: \"sentiment-classifier-v2.1.0\"\n  version: \"2.1.0\"\n  type: \"text-classification\"\n  framework: \"pytorch\"\n  license: \"Apache-2.0\"\n\nprovenance:\n  training_data:\n    source: \"s3:\u002F\u002Facme-datasets\u002Fsentiment-v3\u002F\"\n    hash: \"sha256:abc123...\"\n    data_card_ref: \"https:\u002F\u002Finternal.acme.com\u002Fdata-cards\u002Fsentiment-v3\"\n  training_config:\n    source: \"git:\u002F\u002Fgithub.com\u002Facme\u002Fml-models@abc123\"\n    hyperparameters:\n      learning_rate: 0.00005\n      epochs: 10\n      batch_size: 32\n  build_environment:\n    builder: \"github-actions\"\n    runner: \"ubuntu-22.04\"\n    python: \"3.11.7\"\n    torch: \"2.1.2\"\n    cuda: \"12.1\"\n  build_id: \"gh-actions-12345\"\n  commit_sha: \"abc123def456\"\n  build_timestamp: \"2025-01-15T10:30:00Z\"\n  signed_by: \"ci-bot@acme.iam.gserviceaccount.com\"\n\nperformance:\n  accuracy: 0.94\n  f1_score: 0.93\n  evaluation_dataset: \"s3:\u002F\u002Facme-datasets\u002Fsentiment-eval-v3\u002F\"\n  evaluation_hash: \"sha256:def456...\"\n\nsecurity:\n  vulnerability_scan: \"clean\"\n  sbom_ref: \"ghcr.io\u002Facme\u002Fml-models\u002Fsentiment:v2.1.0.sbom\"\n  last_security_review: \"2025-01-10\"\n  known_limitations:\n    - \"May produce biased outputs for underrepresented languages\"\n    - \"Not evaluated for adversarial robustness\"\n```\n\n## Registry Scanning\n\n```bash\n# Scan model-serving image for CVEs\ntrivy image ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:v2.1.0\n\n# Generate SBOM for the serving container\nsyft ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:v2.1.0 -o spdx-json > serving-sbom.json\n\n# Scan SBOM for vulnerabilities\ngrype sbom:serving-sbom.json --fail-on critical\n\n# Check for known-malicious model files (pickle scanning)\npip install fickling\nfickling --check model.pkl\n```\n\n### Automated Registry Scan Pipeline\n\n```yaml\n# .github\u002Fworkflows\u002Fregistry-scan.yml\nname: Nightly Registry Scan\non:\n  schedule:\n    - cron: '0 2 * * *'\n\njobs:\n  scan:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        image:\n          - ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:latest\n          - ghcr.io\u002Facme\u002Fml-models\u002Fembedding-serving:latest\n          - ghcr.io\u002Facme\u002Fml-models\u002Frag-api:latest\n    steps:\n      - name: Scan image\n        run: |\n          trivy image --severity CRITICAL,HIGH \\\n            --exit-code 1 \\\n            --format json \\\n            --output scan-$(echo ${{ matrix.image }} | tr '\u002F:' '-').json \\\n            ${{ matrix.image }}\n\n      - name: Verify signatures are still valid\n        run: |\n          cosign verify \\\n            --certificate-identity=ci-bot@acme.iam.gserviceaccount.com \\\n            --certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com \\\n            ${{ matrix.image }}\n```\n\n## Promotion Policy Enforcement\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n\"\"\"model_promotion_gate.py - Verify model meets all promotion criteria.\"\"\"\n\nimport subprocess\nimport json\nimport sys\n\ndef check_signature(image: str) -> bool:\n    result = subprocess.run(\n        [\"cosign\", \"verify\", \"--certificate-identity=ci-bot@acme.iam.gserviceaccount.com\",\n         \"--certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef check_vulnerabilities(image: str) -> bool:\n    result = subprocess.run(\n        [\"trivy\", \"image\", \"--severity\", \"CRITICAL\", \"--exit-code\", \"1\",\n         \"--quiet\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef check_sbom_exists(image: str) -> bool:\n    result = subprocess.run(\n        [\"cosign\", \"verify-attestation\", \"--type\", \"cyclonedx\",\n         \"--certificate-identity=ci-bot@acme.iam.gserviceaccount.com\",\n         \"--certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef check_model_card(image: str) -> bool:\n    result = subprocess.run(\n        [\"cosign\", \"verify-attestation\", \"--type\", \"custom\",\n         \"--certificate-identity=ci-bot@acme.iam.gserviceaccount.com\",\n         \"--certificate-oidc-issuer=https:\u002F\u002Faccounts.google.com\", image],\n        capture_output=True, text=True,\n    )\n    return result.returncode == 0\n\ndef main():\n    image = sys.argv[1]\n    checks = {\n        \"signature_valid\": check_signature(image),\n        \"no_critical_cves\": check_vulnerabilities(image),\n        \"sbom_attached\": check_sbom_exists(image),\n        \"model_card_present\": check_model_card(image),\n    }\n    all_passed = all(checks.values())\n    for name, passed in checks.items():\n        status = \"PASS\" if passed else \"FAIL\"\n        print(f\"  [{status}] {name}\")\n    if not all_passed:\n        print(\"Promotion BLOCKED: not all checks passed.\")\n        sys.exit(1)\n    print(\"Promotion APPROVED: all checks passed.\")\n\nif __name__ == \"__main__\":\n    main()\n```\n\n## Runtime Hardening\n\n- Run inference containers as non-root.\n- Apply egress restrictions to prevent unauthorized downloads.\n- Mount model volumes read-only when possible.\n- Alert on unsigned artifact pull attempts.\n- Use `safetensors` format instead of pickle to prevent deserialization attacks.\n\n```yaml\n# kubernetes deployment hardening\napiVersion: apps\u002Fv1\nkind: Deployment\nmetadata:\n  name: model-serving\nspec:\n  template:\n    spec:\n      securityContext:\n        runAsNonRoot: true\n        runAsUser: 1000\n        fsGroup: 1000\n      containers:\n        - name: inference\n          image: ghcr.io\u002Facme\u002Fml-models\u002Fsentiment-serving:v2.1.0\n          securityContext:\n            readOnlyRootFilesystem: true\n            allowPrivilegeEscalation: false\n            capabilities:\n              drop: [\"ALL\"]\n          volumeMounts:\n            - name: model-weights\n              mountPath: \u002Fmodels\n              readOnly: true\n          resources:\n            limits:\n              memory: \"4Gi\"\n              nvidia.com\u002Fgpu: \"1\"\n      volumes:\n        - name: model-weights\n          persistentVolumeClaim:\n            claimName: model-weights-pvc\n            readOnly: true\n```\n\n## Kyverno Policy for Admission Control\n\n```yaml\napiVersion: kyverno.io\u002Fv1\nkind: ClusterPolicy\nmetadata:\n  name: require-signed-model-images\nspec:\n  validationFailureAction: Enforce\n  rules:\n    - name: verify-model-image-signature\n      match:\n        any:\n          - resources:\n              kinds: [\"Pod\"]\n              namespaces: [\"ml-serving\"]\n      verifyImages:\n        - imageReferences: [\"ghcr.io\u002Facme\u002Fml-models\u002F*\"]\n          attestors:\n            - entries:\n                - keyless:\n                    subject: \"ci-bot@acme.iam.gserviceaccount.com\"\n                    issuer: \"https:\u002F\u002Faccounts.google.com\"\n```\n\n## Troubleshooting\n\n| Problem | Cause | Solution |\n|---------|-------|----------|\n| `cosign verify` fails with \"no matching signatures\" | Image was pushed without signing | Re-run the signing step; check CI pipeline logs |\n| Provenance attestation missing | SLSA generator not configured | Add slsa-github-generator to the build workflow |\n| Trivy reports CVEs in base image | Stale base image | Update `FROM` image in Dockerfile; rebuild and re-sign |\n| Pickle deserialization warning | Model saved in unsafe format | Convert to safetensors: `model.save_pretrained(\".\", safe_serialization=True)` |\n| Keyless verification fails | Wrong OIDC issuer or identity | Check `--certificate-identity` and `--certificate-oidc-issuer` flags |\n| Model card not found for artifact | Attestation not attached to digest | Attach with `cosign attest --predicate model-card.yaml --type custom IMAGE` |\n\n## Related Skills\n\n- sbom-supply-chain (`sbom-supply-chain`) - Generate SBOM and provenance evidence\n- container-hardening (`container-hardening`) - Harden runtime container posture\n- model-registry-governance (`model-registry-governance`) - Controlled lifecycle and approvals\n\n## Limitations\n\n- Apply guidance only within authorized scope; test destructive steps in non-production first.\n- Docs-only import: upstream scripts and templates not bundled.\n\n### Example\n\n```bash\n# Read-only first: inventory before any active step.\nwhich \u003Ctool> && \u003Ctool> --help | head -n 20\n```\n\n> Adapted from [BagelHole\u002FDevOps-Security-Agent-Skills](https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills) (MIT); frontmatter, When to Use\u002FLimitations, and safety boundaries added for upstream compliance. Docs-only import: helper scripts and templates not bundled.\n",{"name":5,"risk":43,"source":44,"license":14,"category":23,"metadata":45,"date_added":48,"description":7,"source_repo":49,"source_type":31,"compatibility":50,"license_source":51},"safe","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills",{"author":46,"version":47},"devops-skills","1.0","2026-09-20","BagelHole\u002FDevOps-Security-Agent-Skills","Requires the relevant security tooling (scanners, vault CLIs) and an authorized scope for any active assessment. Docs-only; helper scripts and templates not bundled.","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE","f3312ba749561b6159f477dbfc9313c875d40a56",".agents\u002Fskills_archive\u002Fmodel-supply-chain-security","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612","2026-10-25 23:50:58",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill model-supply-chain-security",{"tool":63,"command":64},"bunx","bunx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill model-supply-chain-security",{"tool":66,"command":67},"pnpm","pnpm dlx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill model-supply-chain-security","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fmodel-supply-chain-security\u002FSKILL.md",true,[],[72,94,117,141,169,193],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":83,"publishedAt":38},"01M6Q0FA5FZ410Z33Z3TFQ4DBA","zero-trust","Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzero-trust\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[84,85,86,87,36,88,74,89,34,90,91,33,31,25,29,92,28,27,26,93],"ZeRO","trust","zero trust","architecture","verification","segmentation","access","configure","critical","implementing",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":38},"01M6Q0F1YZJW3KX5FBKEVZ8CV4","zcode-delegate","Delegate coding tasks to the Z.AI ZCode CLI only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzcode-delegate\u002FSKILL.md",[],[101,102,103,104,105,106,107,108,109,21,110,111,112,33,113,31,114,115,92,116],"delegate","zcode","zcode delegate","review","cli","orchestration","tasks","run","Bash","node","read","orchestrator","files","desktop app","app","agent-orchestration",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":38},"01M6Q0ETK41VGNMYEXW0T00AJN","youtube-transcript","Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript\u002FSKILL.md",[],[124,125,126,43,127,128,129,130,131,132,133,134,135,31,25,136,137,138,139,140],"transcript","youtube transcript","youtube","github","codex","research","license","https","text","fetch","tooling","clean","local","output","deepapi","youtube transcripts","blob",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":158,"publishedAt":38},"01M6Q0EPPH2PVMDW40017F8WX0","youtube-transcript-skills","Fetch YouTube video transcripts, search videos\u002Fchannels, browse channels, and extract playlists via the getyoutubetranscript.com API - free tier, no card required.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript-skills\u002FSKILL.md",[147,150,153],{"categoryNo":148,"categoryName":149,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":151,"categoryName":152,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":154,"categoryName":155,"taxonomyType":156,"taxonomyTypeDesc":157},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[124,125,126,159,43,160,127,128,130,161,162,163,164,133,165,31,25,166,167,168],"youtube transcript skills","gemini","search","api","Video","browse","api-integration","free","card","channels",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":179,"publishedAt":38},"01M6Q0EAB96PX83W5PTE8A0R8D","youtube-notetaker","Turn YouTube talks into local study notes with slides, transcripts, editable annotations, and a markdown-backed viewer.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-notetaker\u002FSKILL.md",[175,178],{"categoryNo":176,"categoryName":177,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":151,"categoryName":152,"taxonomyType":81,"taxonomyTypeDesc":82},[126,180,181,105,43,182,183,184,185,130,163,186,187,188,189,25,190,136,191,192],"youtube notetaker","notetaker","workflow","official","notes","code","markdown","slides","annotations","README","study","dair-academy","viewer",{"skillNo":194,"name":195,"nameZh":6,"description":196,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":197,"categories":198,"keywords":200,"publishedAt":38},"01M6Q0E55F0GW5MX48V8HXS8B5","youtube-full","Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-full\u002FSKILL.md",[199],{"categoryNo":148,"categoryName":149,"taxonomyType":81,"taxonomyTypeDesc":82},[201,126,202,203,43,160,161,204,205,162,163,164,133,206,165,31,25,166,207,139],"youtube full","full","google","server","dlp","credits","automatic"]