- Implemented `resolveApiAssetUrl` function to normalize asset URLs based on API base. - Updated `MedialibImage` component to utilize new asset URL resolution and added support for alt text and class properties. - Enhanced image loading behavior with improved width measurement and focal point handling. - Added placeholder image handling and improved accessibility with alt text. - Introduced new test script for auditing broken links in skill documentation. - Expanded seeded test content to include medialib entries and updated related tests for pagebuilder previews. - Improved global setup and teardown logging for clarity on seeded content management.
7.9 KiB
name, description
| name | description |
|---|---|
| security-hardening-and-token-strategy | Apply current tibi-server security practices to website projects. Covers token strategy, secret handling, rate limiting, bulk-permission safety, cookie settings, risky hook capabilities, and secure operator decisions for this stack. |
security-hardening-and-token-strategy
When to use this skill
Use this skill when:
- setting up or reviewing authentication and token usage on this stack
- deciding how admin tokens, JWT auth, and token permissions should be used
- hardening hooks, actions, and project config against current upstream security risks
- reviewing bulk permissions, rate limiting, cookies, secrets, or risky server-side capabilities
Goal
Keep projects on this starter aligned with the current tibi-server security model and with the security-sensitive operator decisions the stack exposes.
This is not a generic web-security primer. It is the practical security workflow for this repo family.
Source of truth
Use these sources when implementing or reviewing security decisions:
tibi-server/docs/05-authentication.mdtibi-server/docs/14-security.mdtibi-server/docs/17-field-level-permissions.mdtibi-server/docs/02-configuration.md- project config and collection/action permission YAML files
Security review order
When asked to harden a project, inspect in this order:
- secret sourcing in config/env
- token type and scope
- collection/action permissions
- bulk permission exposure
- field-level restrictions
- rate limiting and cookie settings
- risky hook capabilities such as outbound fetch or exec
This prevents “secure enough” changes that leave the real attack surface untouched.
Authentication surfaces
This stack exposes multiple auth mechanisms. Do not mix them casually.
- JWT user auth
- refresh-token cookie flow
- admin tokens
- token-based permission sets for narrower machine access
Recommended default:
- use JWT user auth for real users and editor/admin sessions
- use refresh cookies for session continuation where appropriate
- use admin tokens only for system/admin/ops flows that truly need them
- use token permissions for narrow machine integrations
Token header distinction
Use the right header for the right surface:
- system-level API such as project CRUD, admin reload, shutdown:
X-Admin-Token - collection-level CRUD via static project token:
Token - JWT-authenticated user flow:
X-Auth-Token
Do not assume a working Token header implies system-level admin rights.
Secret handling
Do not keep production secrets as committed literals if the deployment can source them from env or operator-managed secrets.
Review at minimum:
- JWT secrets
- SMTP credentials
- admin tokens
- external API keys
- LLM/embedding provider keys
If secrets are hardcoded in committed config, treat that as a structural problem, not as cleanup trivia.
Bulk permission safety
Bulk operations are more dangerous than single-document mutations.
Important rule:
- boolean
post: true/put: true/delete: truedoes not imply bulk access - bulk requires object-form permissions with
bulk: true
Example:
permissions:
user:
methods:
post:
allow: true
bulk: true
Do not enable bulk access casually in website projects. Most editorial workflows do not need it.
Field-level security
Security on this stack is not only collection-method based.
Review all of these layers together:
- collection methods
readonlyFieldshiddenFields- field-level
readonly/hidden - eval-based field rules
- collection visibility in the admin UI
If a field should not be editable or visible, enforce that on the server. Do not rely on frontend omission.
Rate limiting and login hardening
Current upstream tibi-server supports login rate limiting with exponential backoff.
Review these config points:
ratelimit.enabledratelimit.loginInitialDelayratelimit.loginMaxDelayratelimit.loginResetAfter
Security implication:
- a project may look fine in normal use while still being too soft against brute-force attempts if rate limiting is not configured as expected
For serious deployments, do not leave this unreviewed just because login works.
Cookie and session hardening
Refresh-token flows should respect the target environment.
Review:
api.secureCookies- HTTPS vs local HTTP expectations
- whether debugging shortcuts are accidentally bleeding into production config
Do not weaken secure-cookie behavior globally just to make a dev shortcut work.
Query-parameter token risk
Token-based permissions can be passed via query parameters in some cases, but this is a documented risk surface.
If query tokens are unavoidable:
- scope them narrowly
- avoid logging full URLs with sensitive query strings
- understand proxy, history, and referrer exposure
Prefer header-based transport whenever possible.
Risky hook capabilities
Current tibi-server exposes powerful capabilities in hooks. Treat them as explicit design decisions, not utilities.
Particularly important:
context.http.fetch()/context.http.fetchStream()can create SSRF riskcontext.exec.command()can create command-execution risk- broad filesystem/network access in hooks should not be treated as harmless
If a feature can be implemented without shell execution or arbitrary internal fetches, prefer the safer path.
When such capabilities are used, document:
- why they are necessary
- what the allowed target surface is
- what the safer rejected alternatives were
CORS configuration
CORS follows a hierarchy. Configure it deliberately instead of widening it reactively.
Levels:
- server-level
config.yml - project-level
api/config.yml - collection/action-level YAML overrides
For typical website projects on this starter, the default proxy setup often means no aggressive cross-origin opening is required. Add explicit CORS only when the real deployment needs external origins.
Recommended implementation patterns
Public form workflow
Recommended shape:
- public action with narrow methods
- server-side validation
- no admin token in the browser
- separate internal persistence only when truly required
Integration token
Recommended shape:
- dedicated narrow token permission set
- minimal collection/action scope
- header-based transport preferred
Sensitive internal fields
Recommended shape:
- use hidden/readonly restrictions explicitly
- keep admin UI aligned with those restrictions
- do not let previews depend on hidden-only data
Hook that calls external systems
Recommended shape:
- fixed or validated targets
- no user-controlled arbitrary internal fetches
- no shell execution unless unavoidable
Anti-patterns
- hardcoded production secrets in committed config
- broad admin tokens used for normal frontend or integration traffic
- bulk permissions enabled without a concrete operator need
- risky hook capabilities treated as harmless helpers
- collection security solved in the UI instead of the server
- production cookie or rate-limit settings weakened for convenience
Verification checklist
After security-relevant changes, verify all of these:
- secrets are sourced appropriately
- token type matches the intended actor and scope
- bulk permissions are not broader than necessary
- readonly/hidden behavior is correct on the API
- rate limiting and cookie settings match the environment
- risky hook capabilities are constrained by design
yarn validatestays clean
What an LLM should inspect first
When asked to harden or design secure access on this starter, inspect in this order:
tibi-server/docs/05-authentication.mdtibi-server/docs/14-security.mdtibi-server/docs/17-field-level-permissions.md- the relevant collection/action permission sets
- secret sourcing in config/env
- whether hooks use risky capabilities like outbound fetch or exec
This prevents working implementations that quietly widen the attack surface.