lxbme opened a new pull request, #3455:
URL: https://github.com/apache/apisix-dashboard/pull/3455
Please answer these questions before submitting a pull request, **or your PR
will get closed**.
**Why submit this pull request?**
- [x] Bugfix
- [ ] New feature provided
- [ ] Improve performance
- [ ] Backport patches
**What changes will this PR take into?**
Opening a credential's plugin card in the read-only **View** drawer rendered
its secret verbatim — a key-auth `key`, a basic-auth `password`, a jwt-auth
`secret` — with no interaction beyond opening the card. The same drawer shows
plugin configs on routes, services and global rules, so any plugin embedding a
token appeared the same way.
Those values now render as `••••••`, with a **Show secrets** button to
reveal them. This takes secrets out of the default read path: shoulder-surfing,
screenshots, screen shares, and a browser left open on a detail page.
**The list of sensitive fields comes from the gateway.** `GET
/apisix/admin/plugins?all=true` — the request that already drives the plugin
editor — returns `encrypt_fields` inside each plugin's `schema` and
`consumer_schema`. On 3.17.0 that covers 40 plugins:
| plugin | `encrypt_fields` |
| --- | --- |
| `key-auth` | `["key"]` |
| `basic-auth` | `["password"]` |
| `jwt-auth` | `["secret"]` |
| `hmac-auth` | `["secret_key"]` |
| `limit-count` | `["redis_password", "sentinel_password"]` |
| `openid-connect` | `["client_secret", "client_rsa_private_key",
"session.secret", "session.redis.password"]` |
| `ai-proxy` | `["auth.header", "auth.query",
"auth.gcp.service_account_json", "auth.aws.secret_access_key", …]` |
| `kafka-logger` | `["brokers.sasl_config.password"]` |
…plus `clickhouse-logger`, `elasticsearch-logger`, `splunk-hec-logging`,
`aws-lambda`, `azure-functions`, `authz-keycloak`, `saml-auth`,
`google-cloud-logging`, and others. Reading the mask from the gateway means it
stays correct as plugins change, third-party plugins are covered as soon as
they declare it, and no extra request is made — the data already arrives with
the schema the drawer receives.
One detail worth flagging for review: the gateway emits **flat dotted paths
even when a segment crosses an array** — `kafka-logger`'s
`brokers.sasl_config.password` where `brokers` is `type: array`, and
`ai-proxy-multi`'s `instances.auth.header`. A walker that treats every segment
as an object property finds nothing there, returns the config untouched, and
leaves the password in plaintext — a failure that looks exactly like success.
`redactByPaths` fans out over arrays, and a unit test pins it with a
two-element array so a first-element-only bug also fails.
### The SSL private key field
The Admin API does not return private keys: `GET /apisix/admin/ssls/{id}`
yields `cert`, `sni`, `id` and timestamps. The field is therefore always empty,
and since it is `required`, Save is blocked by the browser's generic "please
fill out this field" — so changing an SSL's SNI requires re-pasting a private
key, with nothing on the page explaining why.
`e2e/tests/ssls.crud-required-fields.spec.ts` works around this today ("Click
Cancel instead of Save to avoid validation issues with empty key").
Both private-key fields now carry a `••••••` placeholder and the note *"The
gateway never returns private keys. Enter the key again to save any change."*
**Related issues**
#3416
**Checklist:**
- [x] Did you explain what problem does this PR solve? Or what new features
have been added?
- [x] Have you added corresponding test cases?
- [ ] Have you modified the corresponding document?
- [x] Is this PR backward compatible? If it is not backward compatible,
please discuss on the mailing list first
### Tests
Unit tests cover `redactByPaths`: nested paths, the array fan-out above, a
declared path absent from the config, non-string leaves, no mutation of the
input, and tolerance of a malformed `encrypt_fields` — the field crosses the
network, so its shape is validated rather than assumed.
An e2e spec covers both directions. One test asserts the plaintext secret is
**absent** from the page while `••••••` is present, that view mode exposes no
Save control, and that Show secrets brings the real value back. The other
asserts that **edit mode receives the real config** — the direction that
matters, since redaction leaking into a mutable mode would write `••••••` over
a live credential on save.
Both were mutation-tested: reverting the drawer change makes the first fail;
removing the view-mode guard so redaction reaches edit mode makes the second
fail. Each fails only for its own regression.
Verified: `pnpm test` 93/93, `pnpm lint`, `pnpm exec tsc -b`, and a
production `pnpm build` all clean; e2e green across `e2e/tests/regression/` and
both `ssls.crud-*` specs. Checked by hand in Chrome in English and Chinese —
including that revealing a secret and reopening the drawer starts masked again.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]