# Ratify Tag to Digest Mutation
Currently, Ratify allows subject image references to be specified via tag or digest. Tags are mutable and thus not guaranteed to be referencing the same/correct image every time. Ratify should:
- Require all subject references to be specified via digest
- Implement a new tag-to-digest mutation endpoint for the ratify `httpserver` which will return the full digest reference string of a tag-specified reference input. This endpoint can be leveraged by a new External mutating data provider defined for Ratify which will be invoked by Gatekeeper's mutation webhook.
## Add Mutation endpoint
Add a new endpoint `/ratify/gatekeeper/v1/mutate`. We will also add the accompanying handler which will utilize the referrer store to fetch the subject descriptor which will have the digest in it.
The ORAS auth provider already handles all registry authentication exchanges. As a result, no special authentication logic will need to be handled for this endpoint. However, the first authentication exchange, which is the longest, will now happen during the mutation since mutation occurs before admission. It is possible that the request could time out since the default mutation webhook timeout is 1 second (not 3 seconds).
### Add new Kubernetes templates
There doesn't seem to be GK funcitonality to have a single Provider CRD with multiple endpoints. Therefore, we must define a new provider. We will also rename the current provider to `ratify-admission-provider`
```
apiVersion: externaldata.gatekeeper.sh/v1alpha1
kind: Provider
metadata:
name: ratify-mutation-provider
spec:
url: {{ if .Values.provider.auth }}https{{ else }}http{{ end }}://{{ include "ratify.fullname" .}}.{{ .Release.Namespace }}:6001/ratify/gatekeeper/v1/mutation
timeout: 7
{{- if .Values.provider.tls.skipVerify }} # allow gatekeeper with version < 3.9.x
insecureTLSSkipVerify: true # enable this if the provider uses HTTP so that Gatekeeper can skip TLS verification.
{{- end }}
{{- if .Values.provider.auth }}
caBundle: {{ required "You must provide .Values.provider.tls.cabundle when .Values.provider.auth is set" .Values.provider.tls.cabundle }}
{{- end }}
```
We also must define the Assign resource defintion which GK uses to perform the mutation on the correct resource.
```
apiVersion: mutations.gatekeeper.sh/v1beta1
kind: Assign
metadata:
name: mutate-subject-reference
spec:
match:
scope: Namespaced
kinds:
- apiGroups: ["apps"]
kinds: ["Deployment", "Pod"]
excludedNamespaces: ["gatekeeper-system"]
applyTo:
- groups: ["apps"]
kinds: ["Deployment", "Pod"]
versions: ["v1"]
location: "spec.template.spec.containers[name:*].image"
parameters:
assign:
externalData:
provider: ratify-mutation-provider
```
## Support only digest
We have to add reference checking logic at CLI and server level so error is thrown at propogated early on.
We also need to remove the first call to registry to resolve the subject descriptor. This will require slightly altering the code to create the descriptor instead of using the one returned by registry.
## Questions
1. Can there be multiple references provided in a single mutation request from GK?
2. Will the 1 second timeout pose an issue?