Skip to content

feat: config to never reveal sensitive fields - #443

Open
Fasp96 wants to merge 1 commit into
ash-project:mainfrom
Fasp96:feat/never-reveal-sensitive-fields
Open

Fasp96 wants to merge 1 commit into
ash-project:mainfrom
Fasp96:feat/never-reveal-sensitive-fields

Conversation

@Fasp96

@Fasp96 Fasp96 commented Nov 6, 2026

Copy link
Copy Markdown

Sensitive attributes show as --redacted--, but the eye icon next to them shows the value, and there is no way to turn that off. That is a problem when the admin can be opened on production data: anyone who can open it can read every credential. Hiding the icon with CSS doesn't help, because the reveal event can be sent without it.

This adds an opt-in setting:

config :ash_admin, :reveal_sensitive_fields?, false

With it, a sensitive value never reaches the browser:

  • SensitiveAttribute renders only --redacted--, without the icon. It also refuses the toggle event, which can be sent without the icon.
  • DataTable turns off filtering, sorting and search on sensitive columns. Otherwise the rows that match leak the value: a substring filter on a token column rebuilds the token one guess at a time. Cinder already ignores filter, sort and search events for columns that don't allow them, so this also covers events sent by hand.
  • Update forms leave sensitive attributes out. They were password inputs prefilled with the stored value, which puts the value in the page's HTML. They can still be set when creating a record.

Fields listed in show_sensitive_fields are unaffected, and the default (true) keeps today's behaviour. Not covered: a sensitive primary key still appears in links, as before.

I made it application config, like :title and :max_primary_key_byte_size, since it's an app-wide policy. I'm happy to make it a router option like host_app_path instead if you prefer.

Tests are in test/sensitive_fields_test.exs. They use a new Credential fixture in its own test domain, because adding it to AshAdmin.Test.Domain would change the dropdown tests' groups. They cover the default reveal, the record page with a reveal event sent without the icon, table filters, sorts and search (including events sent by hand), and update and create forms. Locally, mix check passes apart from hex_audit, which fails on main too (retired ash_sql 0.8.4, ecto advisory). I didn't run dialyzer or reuse locally.

`config :ash_admin, :reveal_sensitive_fields?, false` keeps sensitive
values redacted: no eye icon, and the reveal event is refused when sent
without it; no filtering, sorting or searching on sensitive columns,
which would leak the values one row match at a time; and update forms
leave sensitive attributes out instead of filling them with the stored
value. `show_sensitive_fields` still applies. The default is unchanged.
@zachdaniel

Copy link
Copy Markdown
Contributor

One thing: if an update action has an argument with the same name as the sensitive attribute (i.e argument :token + set_attribute(:token, arg(:token))), the input still gets prefilled with the stored value, since AshPhoenix.Form.value/2 falls back to the record's data. Can we render those with no value and add a test for it? 😄

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants