{
  "openapi": "3.1.1",
  "info": {
    "title": "Container Image Explorer API",
    "version": "1.0.0",
    "summary": "Inspect a container image: platforms, layers, base image, root user, labels and cosign signature.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://containerimageexplorer.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Inspect a container image: platforms, layers, base image, root user, labels and cosign signature.",
        "description": "Reads an image straight from its registry (Docker Hub, GHCR, Quay or any OCI registry with anonymous pull): the index and per-platform manifests, layer sizes, digest, and the config blob (creation date, user, environment variable names, OCI labels such as source and revision, build history). Flags root user, likely secrets in env / build args, end-of-life base distributions, missing provenance labels and whether a cosign signature is published.\n\nMethodology:\n- Registry access follows the Docker / OCI distribution token flow: an anonymous request is answered with a WWW-Authenticate Bearer challenge, a pull-scoped token is requested from the advertised realm (auth.docker.io, ghcr.io/token, …) and the request is retried. Only public images work.\n- GET /v2/<repo>/manifests/<tag> with OCI + Docker media types; for an index / manifest list the platforms are listed and the requested platform manifest is fetched. BuildKit attestation manifests (provenance / SBOM, platform unknown/unknown) are counted. The config blob is fetched by digest and its SHA-256 is checked against the manifest.\n- Cosign signatures are looked up by cosign's tag convention (sha256-<digest>.sig) for the image digest. Signatures stored only via the OCI referrers API or Sigstore bundles are not detected, and a found signature is not cryptographically verified here.\n- Root user: config.User empty, root or 0. Secrets: env names and build-arg names (from history \"RUN |n NAME=…\") matching password/secret/token/key patterns; values are never shown.\n- Base distribution is guessed from history, labels and env text and compared with an endoflife.date snapshot (2026-10-14). This tool does NOT scan layers for vulnerable packages — that needs a scanner such as Trivy or Grype run against the image.",
        "tags": [
          "security"
        ],
        "x-mcp-tool": "container_image_explorer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContainerImageExplorerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Pasted manifest + config of an illustrative Node app image (offline)",
                  "value": {
                    "manifestJson": "{\n \"schemaVersion\": 2,\n \"mediaType\": \"application/vnd.oci.image.manifest.v1+json\",\n \"config\": {\n  \"mediaType\": \"application/vnd.oci.image.config.v1+json\",\n  \"digest\": \"sha256:7db22f7fd3e9f15baca89f8609989af9e7f39dd33dc62fc1186370a7bc4c7ad8\",\n  \"size\": 1588\n },\n \"layers\": [\n  {\n   \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n   \"digest\": \"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n   \"size\": 50450000\n  },\n  {\n   \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n   \"digest\": \"sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\n   \"size\": 39820000\n  },\n  {\n   \"mediaType\": \"application/vnd.oci.image.layer.v1.tar+gzip\",\n   \"digest\": \"sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\",\n   \"size\": 12300000\n  }\n ]\n}",
                    "configJson": "{\"architecture\":\"amd64\",\"os\":\"linux\",\"created\":\"2024-03-12T09:41:07Z\",\"config\":{\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\",\"NODE_VERSION=18.19.1\",\"YARN_VERSION=1.22.19\",\"NODE_ENV=production\",\"SENTRY_DSN=https://public@sentry.example/1\"],\"Cmd\":[\"node\",\"server.js\"],\"WorkingDir\":\"/app\",\"ExposedPorts\":{\"3000/tcp\":{}},\"Labels\":{\"org.opencontainers.image.source\":\"https://github.com/example/shop-api\",\"org.opencontainers.image.revision\":\"9f2c1d7e4b5a\",\"org.opencontainers.image.base.name\":\"docker.io/library/node:18-buster\"}},\"rootfs\":{\"type\":\"layers\",\"diff_ids\":[\"sha256:1111111111111111111111111111111111111111111111111111111111111111\",\"sha256:2222222222222222222222222222222222222222222222222222222222222222\",\"sha256:3333333333333333333333333333333333333333333333333333333333333333\"]},\"history\":[{\"created\":\"2024-02-13T00:00:00Z\",\"created_by\":\"# debian.sh --arch 'amd64' out/ 'buster' '@1707782400'\",\"comment\":\"debuerreotype 0.15\"},{\"created\":\"2024-02-14T00:00:00Z\",\"created_by\":\"ENV NODE_VERSION=18.19.1\",\"empty_layer\":true},{\"created\":\"2024-02-14T00:00:00Z\",\"created_by\":\"RUN /bin/sh -c set -ex && curl -fsSLO https://nodejs.org/dist/v18.19.1/node-v18.19.1-linux-x64.tar.xz && tar -xJf node-v18.19.1-linux-x64.tar.xz -C /usr/local --strip-components=1\"},{\"created\":\"2024-03-12T09:41:05Z\",\"created_by\":\"WORKDIR /app\",\"empty_layer\":true},{\"created\":\"2024-03-12T09:41:07Z\",\"created_by\":\"RUN |1 NPM_TOKEN=npm_xxxxxxxx /bin/sh -c npm ci --omit=dev # buildkit\"},{\"created\":\"2024-03-12T09:41:07Z\",\"created_by\":\"CMD [\\\"node\\\" \\\"server.js\\\"]\",\"empty_layer\":true}]}"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContainerImageExplorerResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "ContainerImageExplorerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "image": {
            "title": "Image reference",
            "type": "string",
            "maxLength": 300
          },
          "platform": {
            "title": "Platform",
            "description": "os/arch[/variant] picked from multi-platform images.",
            "type": "string",
            "maxLength": 40,
            "default": "linux/amd64"
          },
          "manifestJson": {
            "title": "Or paste a manifest / index (JSON)",
            "description": "Offline mode, e.g. output of `docker buildx imagetools inspect --raw <image>`.",
            "type": "string",
            "maxLength": 1000000
          },
          "configJson": {
            "title": "And its config blob (JSON)",
            "description": "e.g. `crane config <image>` or `docker inspect` Config section.",
            "type": "string",
            "maxLength": 2000000
          }
        },
        "required": []
      },
      "ContainerImageExplorerResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "image",
              "digest",
              "mediaType",
              "platforms",
              "attestationManifests",
              "selectedPlatform",
              "layers",
              "totalCompressedBytes",
              "config",
              "baseImage",
              "signature",
              "findings"
            ],
            "properties": {
              "image": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "digest": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "mediaType": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "platforms": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "platform",
                    "digest",
                    "size"
                  ],
                  "properties": {
                    "platform": {
                      "type": "string"
                    },
                    "digest": {
                      "type": "string"
                    },
                    "size": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  }
                }
              },
              "attestationManifests": {
                "type": "integer"
              },
              "selectedPlatform": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "layers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "digest",
                    "size",
                    "mediaType"
                  ],
                  "properties": {
                    "digest": {
                      "type": "string"
                    },
                    "size": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "mediaType": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "totalCompressedBytes": {
                "type": "integer"
              },
              "config": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "digestVerified",
                  "created",
                  "ageDays",
                  "os",
                  "architecture",
                  "user",
                  "runsAsRoot",
                  "envNames",
                  "labels",
                  "exposedPorts",
                  "entrypoint",
                  "cmd",
                  "historySteps",
                  "healthcheck"
                ],
                "properties": {
                  "digestVerified": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  },
                  "created": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "ageDays": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "os": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "architecture": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "user": {
                    "type": "string"
                  },
                  "runsAsRoot": {
                    "type": "boolean"
                  },
                  "envNames": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "labels": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    }
                  },
                  "exposedPorts": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "entrypoint": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "cmd": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "healthcheck": {
                    "type": "boolean"
                  },
                  "historySteps": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "created",
                        "createdBy",
                        "emptyLayer"
                      ],
                      "properties": {
                        "created": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdBy": {
                          "type": "string"
                        },
                        "emptyLayer": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              },
              "baseImage": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "label",
                  "distro",
                  "version",
                  "evidence",
                  "eol",
                  "status",
                  "note"
                ],
                "properties": {
                  "label": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "distro": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "version": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "evidence": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "eol": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "supported",
                      "eol",
                      "extended-only",
                      "unknown"
                    ]
                  },
                  "note": {
                    "type": "string"
                  }
                }
              },
              "signature": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "checked",
                  "cosignTag",
                  "found"
                ],
                "properties": {
                  "checked": {
                    "type": "boolean"
                  },
                  "cosignTag": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "found": {
                    "type": [
                      "boolean",
                      "null"
                    ]
                  }
                }
              },
              "findings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "level",
                    "text"
                  ],
                  "properties": {
                    "level": {
                      "type": "string",
                      "enum": [
                        "good",
                        "info",
                        "warning",
                        "bad"
                      ]
                    },
                    "text": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}