# `MishkaCmsCore.Runtime.PageBuilder.CodeSignature`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/page_builder/code_signature.ex#L5)

An HMAC over each stored snippet, so code that did not come through this application does not run.

## What it buys, and it is one thing

Every future arbitrary-database-write bug in this CMS — an injection, a mis-scoped Ash action, a
restored dump somebody tampered with — currently ends in remote code execution, because whatever is
in `events`, `infos` or `helpers` is compiled into the module that serves the site. With signing
on, such a write produces code that **does not run**: the signature will not match, and the
compiler emits an inert clause instead.

It is not a permission check and does not replace one. The resource's policies decide who may
write; this decides whether what is stored was written by this application at all.

## The page still renders

A snippet whose signature is missing or wrong is replaced by a clause that does nothing, and the
rest of the document compiles and serves as normal. The alternative — refusing to compile — turns
a tampered helper into a site-wide outage, which hands whoever tampered with it a better outcome
than they had.

## The cost, stated plainly

**A database restored into another environment runs no page code until it is re-signed.** The key
is per-deployment, so a production dump loaded into staging carries signatures staging cannot
verify. That is the feature working, and it will read as a bug the first time somebody hits it —
`mix mishka.resign_code` is the answer, and the log line says so by name.

## Off unless a key is configured

No key, no signing and no verification: `enabled?/0` is false, and everything behaves exactly as it
did before this module existed. A deployment opts in by setting one, which is the only way to add
this to an existing database without every page stopping at once.

    config :mishka_cms_core, :code_signing_key, System.get_env("CODE_SIGNING_KEY")

# `enabled?`

```elixir
@spec enabled?() :: boolean()
```

Whether this deployment signs and verifies stored code.

False when no key is configured, which is the default and which makes every other function here a
no-op — an existing database keeps working until somebody deliberately turns this on.

# `put`

```elixir
@spec put(map()) :: map()
```

One snippet with its signature attached — what the resources store.

A map with string keys keeps whatever it had; the key is added under the same kind of key the map
already uses, so a snippet that arrived from JSON:API and one that arrived from the editor come out
looking the same.

# `sign`

```elixir
@spec sign(String.t() | nil) :: String.t() | nil
```

The signature for one snippet's code, or `nil` when signing is off.

Normalized first, because a save that only changes indentation must not invalidate the signature
and, more importantly, because the compiler has to compute the same digest from the same text —
`\r\n` from a paste and trailing spaces from an editor are the two ways that goes wrong.

# `trusted?`

```elixir
@spec trusted?(map()) :: boolean()
```

Whether a stored snippet carries a signature this deployment made — what the compiler asks before
it turns the snippet into a clause.

# `valid?`

```elixir
@spec valid?(String.t() | nil, String.t() | nil) :: boolean()
```

Whether `signature` is this deployment's signature for `code`.

Answers true when signing is off — with no key there is nothing to verify, and the compiler must
behave exactly as it did before. Compared in constant time, because a signature is a secret-derived
value and a byte-at-a-time comparison leaks where it stopped matching.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
