Frontend: present API key as an embeddable public identifier (update existing page)
#209 opened on Aug 3, 2026
Repository metrics
- Stars
- (6 stars)
- PR merge metrics
- (PR metrics pending)
Description
Objective: Self-identifying auth · Quarter: Q1 1448 · Size: S · Priority: High Roadmap: Fanar 1448 Q1 & Q2 Roadmap · Task ID: ITQ-24
Context
The API Keys management page already exists (cms-frontend/src/app/core/auth/pages/api-keys/, with util/model/service alongside). This task updates it to present the key as a non-secret public identifier developers can embed in client apps — not a credential to hide.
Why
The UI currently frames keys like secrets (reveal-once, "keep it safe" tone). Decision: keys are now re-viewable — the page must let developers view/copy the full key anytime. To encourage client-side embedding, the messaging and possibly the reveal behavior must change to match the non-secret decision.
Acceptance criteria
- Copy updated: the key is a public app identifier, safe to ship in frontend/mobile bundles; leakage is not a security incident
- Key is re-viewable (decision made): the page shows/copies the full key anytime, not just once on create — remove any "you won't see this again" reveal-once treatment. Depends on the backend making the key retrievable (see ITQ-2 (Itqan-community/cms-backend#407))
- Guidance on how to send it:
X-API-Keyheader, plus the optional per-user identifier header (from ITQ-4 (Itqan-community/cms-backend#410)) - Keep create / rename / revoke / (optional) expiry, scoped to the owner — reuse existing components; login already required
- Strings i18n-ready (ar/en); consistent with Angular 20 / NG-ZORRO patterns already in the page
Notes
Small — it's an update to an existing page, not a new build. No OAuth2 Applications UI involved. Depends on ITQ-2 (Itqan-community/cms-backend#407) + ITQ-3 (Itqan-community/cms-backend#409) for the backend behavior it reflects.
🤝 Before you pick this up
Fanar is an open-source, community-maintained project. For it to outlive any one of us, the people contributing need to genuinely understand how it works internally — that understanding is the thing we're actually building.
We all have AI subscriptions. Using AI to help you work is fine and expected. But if you copy this issue into an agent, paste back whatever it produces, and open a PR you haven't read, you're taking more from this project than you're giving it. Reviewing code that its own author never read or ran costs the maintainers more than writing it would have.
So before you open a PR, please make sure you:
- understand the code you're submitting, well enough to explain why it works
- ran it on your own machine and saw it behave correctly
- tested it — including the cases you expect to fail
If you're not planning to do that on this one, please leave it for someone who will. And if you're stuck partway, say so in the comments — a half-finished PR you understand is far more welcome than a complete one you don't.
🛠️ Implementation & Technical Guidance (Community Addendum)
Target File Paths
cms-frontend/src/app/core/auth/pages/api-keys/api-keys.component.tscms-frontend/src/app/core/auth/pages/api-keys/api-keys.component.htmlcms-frontend/src/assets/i18n/ar.json&en.json
UX & Copy Updates
- Banner Copy: Change alert warning from "Keep this key safe, you will not see it again" to "Public App Identifier: Safe to expose and embed in frontend/mobile applications."
- Re-viewable Key UI: Always display full key or toggleable input mask with a copy button.
Copy Code Generator Integration
- Provide an embed snippet block displaying how to pass headers:
X-API-Key: <YOUR_PUBLIC_KEY>
X-User-ID: <OPTIONAL_ANONYMOUS_USER_ID>
NG-ZORRO Pattern
<nz-input-group [nzSuffix]="copyTemplate">
<input type="text" nz-input [value]="apiKey().key" readonly />
</nz-input-group>
<ng-template #copyTemplate>
<button nz-button nzType="text" (click)="copyApiKey(apiKey().key)">
<i nz-icon nzType="copy"></i>
</button>
</ng-template>