Skip to content
Back to skills

Dotkernel Security

ASecurity

Use when touching anything security-relevant in a Dotkernel project — authentication, OAuth2 or session login, authorization config and role permissions or guards, CORS, content negotiation, session and cookie settings, error handling and error-reporting endpoints, documentation exposure, secrets and *.local.php versus *.global.php, demo credentials, ownership checks, raw DQL or SQL, or adding a dependency. Also use when reviewing a diff for security problems or when asked whether something i...

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
securityjavascriptrustgojavaphpsqlgitapifrontendsecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add dotkernel/dotboost --skill dotkernel-security --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dotkernel Security?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dotkernel Security
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dotkernel-dotkernel-security/badge)](https://www.skillsdirectory.com/skills/dotkernel-dotkernel-security)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dotkernel-security
description: >
  Use when touching anything security-relevant in a Dotkernel project — authentication,
  OAuth2 or session login, authorization config and role permissions or guards, CORS, content
  negotiation, session and cookie settings, error handling and error-reporting endpoints,
  documentation exposure, secrets and *.local.php versus *.global.php, demo credentials,
  ownership checks, raw DQL or SQL, or adding a dependency. Also use when reviewing a diff for
  security problems or when asked whether something is safe to commit.
---

# Security

```text
Applies to
  Projects:  - all
  Packages:  - none
```

Assume every request is hostile. Ignoring security is cheap today and expensive later — lost
data, a GDPR fine, lost client trust. Every item below has a real place in the codebase; check
it rather than reinventing it.

Input validation has its own skill (`dotkernel-input-validation`) — that is the first line and
the most commonly skipped.

## Authentication

| Variant | Mechanism |
| --- | --- |
| API | OAuth 2.0 (`mezzio/mezzio-authentication-oauth2`) — access + refresh tokens |
| Admin / Frontend | session-based login |
| Light / Queue | none in the stock repositories |

For OAuth2 projects:

- Replace or update the default clients before production.
- Review token lifetimes against requirements (commonly one day access, one month refresh); do
  not lengthen without discussion.
- Keys are generated by the repo's key-generation script into a data directory. **Never commit
  them, never edit them, never read them into context.**

For session-based projects: `cookie_httponly`, `cookie_samesite` and `cookie_secure` must stay hardened in
the session config, and every form needs CSRF.

## Authorization

| Variant | Where |
| --- | --- |
| API | RBAC roles and route-name permissions in `config/autoload/authorization.global.php` |
| Admin | roles → permissions in `authorization.global.php`; route name → permission in `authorization-guards.global.php` |
| Frontend | the same two files; guards keyed by route **and controller action** |
| Light / Queue | none |

- **The default differs, and it is the dangerous part.** The API denies a route that has no
  permission entry. The Admin and Frontend guards use `POLICY_ALLOW`: a route or action with no
  guard rule is **open to everyone, guests included**. Forgetting the entry there never surfaces
  as a 403 — it surfaces as an unprotected page.
- **Every new route needs an explicit entry** — per role in the API, a guard rule in Admin and
  Frontend.
- Do not grant anything to a guest role unless the route is genuinely public (registration,
  activation, password recovery).
- Check the role hierarchy — inheritance direction in these config files is not always what
  people assume. Read the comment at the top of the file.
- **Route-level access is not object-level access.** A user permitted to view "an account" must
  only see their own. Use the resource guard mechanism where the project provides one, or an explicit
  ownership check in the service. This is the most common real vulnerability in CRUD code.

## Configuration and secrets

| File | Committed? | May contain secrets? |
| --- | --- | --- |
| `*.global.php` | yes | **no** |
| `*.php.dist` | yes | **no** — placeholders only |
| `*.local.php` | no (git-ignored) | yes |

Never write a credential, key, token, password-bearing DSN or SMTP password into a committed
file. Need a new setting? Add the placeholder to the `.dist` and read it through config.

Development mode enables debug output, error details and disables config caching. It must be
disabled in production.

## HTTP-layer protections

Configured in `config/pipeline.php` and `config/autoload/` — keep the order, and justify any
change to it:

- **CORS** (where present): must be piped **before** the routing middleware. Never widen origins
  to `*` in a committed file.
- **Content negotiation**: honours `Content-Type` and `Accept`; do not bypass it.
- **Malformed body handling**: rejects unparseable payloads early.
- **Error handling**: outermost layer, renders a safe error body. Throw typed exceptions; never
  leak stack traces, SQL, paths or internal class names.
- **Response headers**: security headers are set centrally, not per handler.

## Persistence

Use the query builder with bound parameters. **No string concatenation or interpolation into DQL
or SQL, ever.** Whitelist user-supplied sort and filter values against an explicit column list.
If you believe you need raw SQL, explain why and ask.

## Error-reporting endpoints

Where the project exposes one, it is gated by a token and a permission middleware. Do not disable
the token check or widen allowed IPs in a committed file.

## Documentation exposure

Never document a real credential, internal hostname, or an example payload containing production
data. Interactive documentation should not be enabled in production.

## Dependencies and supply chain

- **Adding, removing or upgrading a Composer or npm package requires explicit user approval.**
  Propose it, name the maintainer, and say why the existing stack cannot cover the need.
- The security-advisories dev dependency refuses known-vulnerable versions. If it blocks an
  install, that is a signal, not an obstacle to route around.
- Let the automated dependency bot drive routine bumps.
- JavaScript is a live supply-chain target — widely used npm packages have been compromised. Use
  `npm audit` and prefer packages from reliable sources.
- Transitive dependencies count too.

## Review checklist for a diff

- [ ] Every write path validates before business logic.
- [ ] Every new route has an explicit authorization entry; no accidental guest access.
- [ ] Object-level ownership checked where a resource belongs to a user.
- [ ] CSRF present and validated on every form (templated projects).
- [ ] No secrets outside `*.local.php`; no keys committed.
- [ ] No raw SQL/DQL interpolation; all parameters bound.
- [ ] Sort/filter values whitelisted; `limit` clamped.
- [ ] Uploads validated and stored outside executable paths.
- [ ] Errors thrown as typed exceptions with no internal detail.
- [ ] No new dependency without approval.
- [ ] Pipeline order unchanged, or the change justified.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.