4020ad62c5
- 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.
263 lines
7.9 KiB
Markdown
263 lines
7.9 KiB
Markdown
---
|
|
name: security-hardening-and-token-strategy
|
|
description: 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.md`
|
|
- `tibi-server/docs/14-security.md`
|
|
- `tibi-server/docs/17-field-level-permissions.md`
|
|
- `tibi-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:
|
|
|
|
1. secret sourcing in config/env
|
|
2. token type and scope
|
|
3. collection/action permissions
|
|
4. bulk permission exposure
|
|
5. field-level restrictions
|
|
6. rate limiting and cookie settings
|
|
7. 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: true` does not imply bulk access
|
|
- bulk requires object-form permissions with `bulk: true`
|
|
|
|
Example:
|
|
|
|
```yaml
|
|
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
|
|
- `readonlyFields`
|
|
- `hiddenFields`
|
|
- 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.enabled`
|
|
- `ratelimit.loginInitialDelay`
|
|
- `ratelimit.loginMaxDelay`
|
|
- `ratelimit.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 risk
|
|
- `context.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:
|
|
|
|
1. secrets are sourced appropriately
|
|
2. token type matches the intended actor and scope
|
|
3. bulk permissions are not broader than necessary
|
|
4. readonly/hidden behavior is correct on the API
|
|
5. rate limiting and cookie settings match the environment
|
|
6. risky hook capabilities are constrained by design
|
|
7. `yarn validate` stays clean
|
|
|
|
## What an LLM should inspect first
|
|
|
|
When asked to harden or design secure access on this starter, inspect in this order:
|
|
|
|
1. `tibi-server/docs/05-authentication.md`
|
|
2. `tibi-server/docs/14-security.md`
|
|
3. `tibi-server/docs/17-field-level-permissions.md`
|
|
4. the relevant collection/action permission sets
|
|
5. secret sourcing in config/env
|
|
6. whether hooks use risky capabilities like outbound fetch or exec
|
|
|
|
This prevents working implementations that quietly widen the attack surface.
|