{
  "schemaVersion": 1,
  "evaluation": {
    "id": "kubectl",
    "testedOn": "2026-10-18",
    "coverage": "local-runtime",
    "summary": "Client-side generation produced a ConfigMap and Secret without a cluster. Kustomize changed a replica count and rejected a file outside its root. Secret data was visibly reversible base64.",
    "identity": {
      "version": "v1.37.1; commit f78e722310e50bcaca9276be22276d9e91d91308",
      "target": "https://dl.k8s.io/release/v1.37.1/bin/windows/amd64/kubectl.exe",
      "integrity": "SHA-256 14b93c4916a6f37a06fbc1f46b0a1d2404c4f9741be09f00d6caf8af3b05f1d3 of the downloaded executable. Matched the official release checksum; detached signatures were not verified."
    },
    "environment": [
      "Windows 11 x64; Python 3.12.10 harness. Raw timestamps use UTC.",
      "Fresh per-tool home, config, cache and temporary directories. Child environments used allowlisted OS/runtime paths without inherited account credentials. Only synthetic local files were used.",
      "Configuration isolation is a test control, not an operating-system sandbox.",
      "KUBECONFIG pointed to a fresh path with no cluster credentials. All manifests and values were synthetic."
    ],
    "checks": [
      {
        "id": "kubectl-version",
        "name": "Pinned client version",
        "method": "Use an isolated KUBECONFIG path with no cluster credentials. Command argument array: [\"kubectl\", \"version\", \"--client\", \"-o\", \"json\"].",
        "expected": "Print only client version information.",
        "observed": "Exit 0. clientVersion.gitVersion=\"v1.37.1\", gitCommit=\"f78e722310e50bcaca9276be22276d9e91d91308\".",
        "outcome": "pass"
      },
      {
        "id": "kubectl-configmap",
        "name": "Generate a ConfigMap locally",
        "method": "Use an isolated KUBECONFIG path with no cluster credentials. Command argument array: [\"kubectl\", \"create\", \"configmap\", \"ionbin-fixture\", \"--from-literal=mode=test\", \"--dry-run=client\", \"-o\", \"json\"].",
        "expected": "Print a ConfigMap without creating a cluster resource.",
        "observed": "Exit 0. kind=ConfigMap, metadata.name=ionbin-fixture, data={\"mode\":\"test\"}.",
        "outcome": "pass"
      },
      {
        "id": "kubectl-secret",
        "name": "Inspect Secret encoding locally",
        "method": "Use an isolated KUBECONFIG path with no cluster credentials. The literal token is synthetic-only, not a real credential. Command argument array: [\"kubectl\", \"create\", \"secret\", \"generic\", \"ionbin-fixture\", \"--from-literal=token=synthetic-only\", \"--dry-run=client\", \"-o\", \"json\"].",
        "expected": "Print the synthetic Secret with base64 data.",
        "observed": "Exit 0. kind=Secret, metadata.name=ionbin-fixture, data.token=\"c3ludGhldGljLW9ubHk=\"; decoding yields synthetic-only.",
        "outcome": "pass"
      },
      {
        "id": "kubectl-kustomize",
        "name": "Render a local replica override",
        "method": "Create overlay/deployment.yaml with:\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: ionbin-fixture\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: ionbin-fixture\n  template:\n    metadata:\n      labels:\n        app: ionbin-fixture\n    spec:\n      containers:\n        - name: app\n          image: example.invalid/fixture:1\nCreate overlay/kustomization.yaml with:\nresources:\n  - deployment.yaml\nreplicas:\n  - name: ionbin-fixture\n    count: 2\n Command argument array: [\"kubectl\", \"kustomize\", \"overlay\"].",
        "expected": "Render the Deployment with replicas=2.",
        "observed": "Exit 0. Rendered one apps/v1 Deployment named ionbin-fixture with spec.replicas=2 and image example.invalid/fixture:1. No image was pulled or resource submitted.",
        "outcome": "pass"
      },
      {
        "id": "kubectl-load-boundary",
        "name": "Reject a file outside the Kustomize root",
        "method": "Create outside.txt containing synthetic-outside-root followed by a newline. Create restricted/kustomization.yaml with:\nconfigMapGenerator:\n  - name: outside-probe\n    files:\n      - ../outside.txt\n Command argument array: [\"kubectl\", \"kustomize\", \"restricted\"].",
        "expected": "Reject loading ../outside.txt outside the selected root.",
        "observed": "Exit 1. Error loading file sources [../outside.txt]: security; the file was not in or below the restricted directory.",
        "outcome": "pass"
      }
    ],
    "findings": [
      {
        "title": "Secret output is encoded, not concealed",
        "basis": "observed",
        "severity": "medium",
        "detail": "The client-side Secret contained c3ludGhldGljLW9ubHk=, which decodes to the authored synthetic-only value. This says nothing about cluster encryption at rest because no cluster was contacted.",
        "practicalAdvice": "Treat Secret manifests, terminal history and generated output as sensitive material; use the team's secret-management process."
      },
      {
        "title": "The default local loading rule rejected this outside file",
        "basis": "observed",
        "severity": "informational",
        "detail": "Kustomize rejected ../outside.txt from the restricted directory. The control was observed for one configMapGenerator path, not every local or remote loading mechanism.",
        "practicalAdvice": "Keep local overlays self-contained and avoid weakening load restrictions without reviewing the additional files."
      },
      {
        "title": "Trust kubeconfig before using it",
        "basis": "documented",
        "severity": "medium",
        "detail": "Kubernetes documents that an untrusted kubeconfig can cause code execution or file exposure. An apparently read-only kubectl command can still trigger configured authentication helpers.",
        "practicalAdvice": "Accept kubeconfig only from trusted sources, inspect exec entries and verify context before any cluster operation."
      }
    ],
    "caveats": [
      "No Kubernetes API server was contacted; local generation cannot establish RBAC, admission behavior or deployment success.",
      "The evaluated client is v1.37.1. Confirm supported version skew before using it with a real cluster."
    ],
    "notTested": [
      "Cluster connections, server-side dry runs, RBAC, admission policy, deployment and client/server compatibility.",
      "Exec authentication plugins, real Secrets, encryption at rest and every Kustomize filesystem or remote-loading boundary."
    ],
    "sources": [
      {
        "label": "kubectl reference",
        "url": "https://kubernetes.io/docs/reference/kubectl/"
      },
      {
        "label": "Kubeconfig trust and context selection",
        "url": "https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/"
      },
      {
        "label": "Kustomize manifest generation",
        "url": "https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/"
      },
      {
        "label": "Secret data and storage caveats",
        "url": "https://kubernetes.io/docs/concepts/configuration/secret/"
      },
      {
        "label": "kubectl repository",
        "url": "https://github.com/kubernetes/kubectl"
      },
      {
        "label": "Apache 2.0 license",
        "url": "https://github.com/kubernetes/kubectl/blob/master/LICENSE"
      }
    ],
    "reportUrl": "/interface-evaluations/kubectl.json"
  }
}
