# OCI annotation meeting + demo https://github.com/opencontainers/image-spec/issues/821 Proposed Standard Annotations: - **org.opencontainers.image.base.digest** - **org.opencontainers.image.base.ref.name** (matches the format of "**org.opencontainers.image.ref.name** Name of the reference for a target (string).") https://github.com/opencontainers/image-spec/blob/master/annotations.md # Motivations 1. identify images based on specific vulnerable base images 1. identify images based on out-of-date base images - "I need an update; do a rebuild" - rebuild could be automated, or just advisory 1. identify a base image seam - enables rebasing without rebuild - rebase could be automated ## Identifying Vulnerable Base Images "Am I vulnerable?" Registries can identify images based on known-vulnerable base images, notify/advise users that they are vulnerable. ## Identifying Old Base Images "Do I need a rebuild?" (for whatever reason) - Proactively scan for rebuildable images - Can notify / inform - Or proactively rebuild and notify "your image is ready" - Kick off deployment pipelines to validate+rollout rebuilt images Either proactive (scan for images in need of a rebuild), or just-in-time (before `docker build`, do I need this?) ---- ## Rebasing In certain constrained cases (e.g., Buildpacks), rebuild can be avoided and base image layers can be replaced directly. This can be useful when rolling out a vulnerability fix at scale across 1000s of running containers (👋 Buildpacks!). Rebasing is _not safe_ in general, and semantics for it are _explicitly not intended as part of the spec_. The standard annotations can be used as a signal though. ### `crane rebase` https://github.com/google/go-containerregistry/blob/main/cmd/crane/rebase.md Requires users to pass old/new base images. We expect these to be `--old_base=[image by digest]` and `--new_base=[image by tag]` With this annotation, `crane rebase my-image:foo` wouldn't need to take tags ### `pack rebase` https://buildpacks.io/docs/concepts/operations/rebase/ Buildpacks annotates base image ref + `topLayer` (see Alternatives) to identify rebase seam ## Demo gcr.io/kontaindotme/rebase-me is based on `ubuntu:16.04`, contains a shell script that does `cat /etc/os-release`. (Let's say it was built back when `ubuntu:latest` was `:16.04`, but time has moved on, we live in the future) ```shell $ docker run gcr.io/kontaindotme/rebase-me NAME="Ubuntu" VERSION="16.04.7 LTS (Xenial Xerus)" ... ``` Let's rebase it on top of current `ubuntu:latest` (`:20.04`) ```shell $ crane rebase \ --original=gcr.io/kontaindotme/rebase-me \ --old_base=ubuntu:16.04 \ --new_base=ubuntu:latest \ --rebased=gcr.io/kontaindotme/rebased ... 2021/02/17 10:51:40 gcr.io/kontaindotme/rebased: digest: sha256:4c0c8fb2348ce31143230e9280e22328271ff5c1233a18f820c4b0775f0e0190 size: 909 ``` * `old_base` _should_ be specified by digest, `crane rebase` allows tags though * if `original` is not actually based on `old_base`, rebase fails * if `original` is already based on `new_base`, do nothing * `rebased` could be same as `original`, to tag over it Now when we run our `rebased` image: ```shell $ docker run gcr.io/kontaindotme/rebased NAME="Ubuntu" VERSION="20.04.1 LTS (Focal Fossa)" ... ``` _(This is not guaranteed to be safe; it's only safe here because my demo image doesn't depend on specifics of the underlying image)_ ### Proposed Annotation If `gcr.io/kontaindotme/rebase-me` had been annotated with: ``` org.opencontainers.image.base.digest: sha256:e74994... org.opencontainers.image.base.ref.name: ubuntu:latest ``` _(saying, "I am based on `ubuntu:latest`, which at the time I was built was `sha256:e74994...`")_ ...then automation could have scanned and found this out-of-date base image: - notified the user if it was a critical vulnerability - put a 🧟‍♂️ badge by it in the UI to tell the user it needs an update - automatically rebuilt it, if source was still available (**image.source** annotation) - automatically rebased it, if we know it's safe ...then handed it to validation and release automation `crane rebase` can be simplified to: ```shell= crane rebase gcr.io/kontaindotme/rebase-me ``` Can assume `rebased`==`original` and derive `old_base` and `new_base` from annotations