2.0 KiB · text History 8ccf537
defmodule GitGud.Audit.Catalog do
  @moduledoc """
  Every action the audit log knows, and the only place one exists.

  Each action names its category (what the log is filtered by), the
  kind of thing it acts on, and the metadata keys it may keep. Keys not
  listed are dropped when the entry is built — that list is what stands
  between a careless call site and a secret value in the table. Never
  list a key that could hold a secret, a token, a webhook URL's path, or
  a hash of any of them.

  Actions are added with the slice that records them
  (`docs/plans/org-audit-log.md`).
  """

  @actions %{
    # CI secrets and variables. The name is the target label; values
    # never appear.
    "repo_secret.set" => %{category: "secrets", target: "secret", keys: ~w()},
    "repo_secret.deleted" => %{category: "secrets", target: "secret", keys: ~w()},
    "repo_variable.set" => %{category: "secrets", target: "variable", keys: ~w()},
    "repo_variable.deleted" => %{category: "secrets", target: "variable", keys: ~w()},
    "org_secret.set" => %{category: "secrets", target: "secret", keys: ~w()},
    "org_secret.deleted" => %{category: "secrets", target: "secret", keys: ~w()},
    "org_variable.set" => %{category: "secrets", target: "variable", keys: ~w()},
    "org_variable.deleted" => %{category: "secrets", target: "variable", keys: ~w()},
    # The pruner's own trace: how much went, from before when.
    "audit.pruned" => %{category: "instance", target: nil, keys: ~w(count cutoff)}
  }

  @categories @actions |> Map.values() |> Enum.map(& &1.category) |> Enum.uniq() |> Enum.sort()

  @doc "The action's definition, or nil for an action that doesn't exist."
  @spec fetch(String.t()) ::
          %{category: String.t(), target: String.t() | nil, keys: [String.t()]} | nil
  def fetch(action) when is_binary(action), do: Map.get(@actions, action)
  def fetch(_), do: nil

  @doc "Every action name."
  def actions, do: Map.keys(@actions)

  @doc "Every category an action belongs to."
  def categories, do: @categories
end