Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Guren Api

ASecurity

Human-browsable Guren API reference — code patterns and examples for every subsystem (Controllers, Models, Routes, Middleware, Authentication, Authorization, Events, Jobs, Queue, Mail, Cache, Validation, Broadcasting, Notifications, Storage, Scheduling, I18n, Encryption, Health Checks, Error Handling, Container/ServiceProvider, Console Commands, API Resources). Use when the user asks "how to", "how does", "example of", or "what is" about a Guren API. Agent-critical signatures are already avai...

29 stars
0 votes
0 copies
0 views
Added 9/23/2026
developmenttypescriptrustgoreactexpresstestingapidatabasefrontendbackend

Works with

cursorcliapi

Security Analysis

A100/100

Scanned 9/23/2026

Install to Claude Code

$npx -y skills add gurenjs/guren --skill guren-api --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Guren Api?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Guren Api
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gurenjs-guren-api/badge)](https://www.skillsdirectory.com/skills/gurenjs-guren-api)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: guren-api
description: Human-browsable Guren API reference — code patterns and examples for every subsystem (Controllers, Models, Routes, Middleware, Authentication, Authorization, Events, Jobs, Queue, Mail, Cache, Validation, Broadcasting, Notifications, Storage, Scheduling, I18n, Encryption, Health Checks, Error Handling, Container/ServiceProvider, Console Commands, API Resources). Use when the user asks "how to", "how does", "example of", or "what is" about a Guren API. Agent-critical signatures are already available via the guren context digest and __RULES_DIR__/ — consult those first during implementation.
---

# Guren API Documentation Skill

You are a documentation assistant for the Guren framework.

> The authoritative signature-level API reference lives in `__RULES_DIR__/*.md` (each file's `globs` frontmatter states the paths it covers); this skill is a subsystem tour for interactive Q&A.

## Your Role

Help users understand and use Guren framework APIs by providing examples, patterns, and source file locations.

## Core Subsystems

### Controllers
Source: `packages/server/src/mvc/Controller.ts`

```typescript
import { Controller } from '@guren/core'
import { pages } from '@/.guren/pages.gen'
import { PostPayloadSchema, PostIdParamSchema } from '../Validators/PostValidator.js'

export default class PostController extends Controller {
  async index() {
    const posts = await Post.all()
    return this.inertia(pages.posts.Index, { posts })
  }

  async show() {
    const { id } = this.validateParams(PostIdParamSchema)  // throws 422
    const post = await Post.findOrFail(id)                  // throws 404
    return this.inertia(pages.posts.Show, { post })
  }

  async store() {
    // routes/web.ts: router.post('/posts', { name: 'posts.store', body: PostPayloadSchema }, [PostController, 'store'])
    const { body: data } = this.validated('posts.store')     // route contract already answered 422
    const user = await this.auth.userOrFail<UserRecord>()    // throws 401 — <T> defaults to Authenticatable, no .id
    const post = await Post.create({ ...data, authorId: user.id })
    return this.redirect('/posts/' + post?.id)
  }
}
```

> **Note:** Server-side controllers use URL string literals for redirects. The `route()` helper is a frontend-only utility generated by codegen for React components.

For public content pages that need no client framework (blog posts, docs),
`this.view(Component, props, options?)` renders a `hono/jsx` component from
`app/View/` to plain SSR HTML — see `rules/controllers-http.md`
("Server-rendered content pages") for the conventions.

**Route contract input**: a route's `params`/`query`/`body` schemas are validated before the action (422 on failure):
- `this.validated('route.name')` → `{ params, query, body }` as the schemas parsed them; typed after `bunx guren codegen`,
  an undeclared segment is `undefined`, and a name other than the served route throws

**Validation helpers** (Zod duck-type — any schema with `safeParse()` works), for routes without a contract:
- `this.validateBody<T>(schema): Promise<T>` — parse request body
- `this.validateQuery<T>(schema): T` — parse query parameters
- `this.validateParams<T>(schema): T` — parse route parameters

All throw `ValidationException` (HTTP 422) on failure.

**Auth helpers:**
- `this.auth.user<T>()` — returns user or null
- `this.auth.userOrFail<T>()` — returns user or throws `AuthenticationException` (401)

### Models
Source: `packages/orm/src/Model.ts`

```typescript
import { defineModel } from '@guren/core'
import { posts } from '@/db/schema'

export class Post extends defineModel(posts) {}

// Usage
await Post.find(1)                              // returns null if not found
await Post.findOrFail(1)                        // throws ModelNotFoundException (404)
await Post.where('published', true).get()
await Post.create({ title: 'Hello' })
```

`ModelNotFoundException` (source: `packages/orm/src/ModelNotFoundException.ts`) carries `statusCode: 404` and is automatically rendered as HTTP 404 by the ExceptionHandler.

**Mass assignment protection** — prevent injection of unintended fields via `create()` / `update()`:

```typescript
export class Post extends defineModel(posts, {
  // Whitelist: only these fields are accepted (recommended).
  // Typed against the table's columns — a typo is a compile error.
  fillable: ['title', 'excerpt', 'body', 'authorId'],
}) {}

export class User extends defineModel(users, {
  base: AuthenticatableModel,
  // The model hashes a plain `password` into `passwordHash`
  optionalOnCreate: ['passwordHash'],
  requireOnCreate: ['password'],
  // Whitelist for mass assignment (credential columns are denied by the base class)
  fillable: ['name', 'email', 'password'],
}) {}
```

- `fillable` (whitelist) — only listed fields pass through to `create()` / `update()`; unlisted input keys **throw `MassAssignmentException`**. The primary key (`id`) is always silently stripped. `static fillable = [...]` on the class also works (untyped) and shadows the option; `hidden`, `visible`, `accessors`, and `appends` have the same typed option forms.
- Credential columns (`passwordHash`, `rememberToken`) **always throw** on authenticatable models — the framework denies them; listing them in `fillable` does not open them
- Enforced by `Model.filterFillable()`, called automatically before persistence
- Always define `fillable` on models that accept user input — this is the second defense layer after Zod validation
- `forceCreate()` / `forceUpdate()` bypass filtering for trusted server-side values (e.g. `passwordHash: 'oauth:...'`). **Never call them with request input**

**Relationships** — declare once, eager-load anywhere:

```typescript
// app/Models/User.ts
export class User extends defineModel(users, { base: AuthenticatableModel, optionalOnCreate: ['passwordHash'] }) {
  static override relationTypes: { posts: HasManyRecord<PostRecord> } = { posts: [] }
}
User.hasMany('posts', () => import('./Post.js').then((m) => m.Post), 'authorId', 'id')

// app/Models/Post.ts
export class Post extends defineModel(posts) {
  static override relationTypes: { author: BelongsToRecord<UserRecord> } = { author: null }
}
Post.belongsTo('author', () => import('./User.js').then((m) => m.User), 'authorId', 'id')

// Eager loading (typed via relationTypes)
await User.with('posts')                       // users[0].posts: PostRecord[]
await User.with('posts.comments')              // nested, dot notation
await User.where('active', true).with('posts').get()  // QueryBuilder
await User.findWith(1, 'posts')                // single record + relations
await User.withCount('posts')                  // users[0].postsCount: number (no rows loaded)
await Post.withPaginate('author', { page: 1 }) // paginated + relations
```

Also available: `hasOne`, `belongsToMany(name, related, pivotTable, foreignPivotKey, relatedPivotKey, parentKey?, relatedKey?)`, `hasManyThrough`, `morphMany`/`morphTo`. There are **no `attach`/`detach`/`sync` pivot helpers and no `firstOrCreate`/`updateOrCreate`** — manage pivot rows via a model on the pivot table (`PivotModel.create(...)` / `PivotModel.delete(...)`), and hand-roll find-or-create with `Model.first(where)` + `Model.create(...)`. Full guide: `docs/en/guides/database.md` (Relationships section).

### Routes
Source: `packages/server/src/mvc/Router.ts`

```typescript
import { Router, requireAuthenticated } from '@guren/core'
import { PostPayloadSchema } from '../app/Http/Validators/PostValidator.js'

export function registerWebRoutes(baseRouter: Router): void {
  // aliasMiddleware() returns a Router carrying the alias name in its type —
  // capture it, or a later .middleware('auth') will not compile.
  const router = baseRouter.aliasMiddleware('auth', requireAuthenticated({ redirectTo: '/login' }))

  router.get('/posts', [PostController, 'index']).name('posts.index')
  // Attach body schema to mutation routes for codegen type extraction
  router.post('/posts', { name: 'posts.store', body: PostPayloadSchema }, [PostController, 'store'])
  router.put('/posts/:id', { name: 'posts.update', body: PostPayloadSchema }, [PostController, 'update'])

  router.middleware('auth').group((auth) => {
    auth.get('/dashboard', [DashboardController, 'index'])
  })
}
```

**Verbs**: `get / post / put / patch / delete / query` share the same overloads;
`router.on(method, path, ...)` covers anything else. `query()` registers HTTP QUERY
(RFC 10008) — safe like GET but body-carrying; read-only handlers only (CSRF skips it),
not expressible in OpenAPI 3.1, not sendable from Inertia forms (use the API client).

**Route contract options** — attach `body`, `params`, `query` schemas to routes:
- Schemas are metadata for codegen (not double-validated for Controller actions)
- `bunx guren codegen` extracts schemas → generates typed `ApiRoutes` interface
- Frontend derives form types via `RouteBody<ApiRoutes, 'route.name'>`

### End-to-End Type Safety
Source: `packages/cli/src/api-client-types.ts`, `packages/inertia-client/src/typed-forms.ts`

Guren provides bidirectional type safety between frontend forms and backend validation:

```
Zod schema (Validator) → Route body option → codegen → ApiRoutes → Frontend form type
                       → Route contract middleware → Runtime validation (422 on failure) → this.validated()
```

`ApiRoutes[...]['body']` is the **request** shape — what the browser sends, before
validation. A coercing schema is rendered as it travels: `z.coerce.date()` is a
`string` in the form and a `Date` in the controller. `['response']` is the other
side, the parsed shape a client gets back.

**1. Define schema once** (Validator file):
```typescript
export const PostPayloadSchema = z.object({ title: z.string().min(1), body: z.string().min(1) })
```

**2. Attach to route** (routes/web.ts):
```typescript
router.post('/posts', { name: 'posts.store', body: PostPayloadSchema }, [PostController, 'store'])
```

**3. Frontend derives types** (after `bunx guren codegen`):
```typescript
import type { ApiRoutes } from '@/.guren/api-client.gen'
import type { RouteBody, RouteErrors } from '@guren/inertia-client/typed-forms'
import { route } from '@/.guren/routes.gen'

type PostFormData = RouteBody<ApiRoutes, 'posts.store'>  // { title: string; body: string }
type PostErrors = RouteErrors<PostFormData>              // Partial<Record<'title' | 'body', string | string[]>>

// Typed form submission
form.post(route('posts.store'))

// Typed navigation
<Link href={route('posts.show', { id: post.id })}>
```

**4. Controller reads the validated body** (the route validated it before the action ran):
```typescript
const { body: data } = this.validated('posts.store')  // typed from the contract after codegen
```

### Middleware
Source: `packages/server/src/http/middleware/`

```typescript
import { defineMiddleware } from '@guren/core'

export const logRequest = defineMiddleware(async (ctx, next) => {
  console.log(ctx.req.method, ctx.req.url)
  await next()
})
```

### Authentication
Source: `packages/server/src/auth/`

```typescript
import { Router, requireAuthenticated } from '@guren/core'

const router = new Router()
  .aliasMiddleware('auth', requireAuthenticated({ redirectTo: '/login' }))

router.middleware('auth').group((auth) => {
  // Protected routes
})

// In controller
const user = await this.auth.user()         // returns user | null
const user = await this.auth.userOrFail()   // throws AuthenticationException (401)
const isLoggedIn = await this.auth.check()  // returns boolean
```

Additional auth features:
- API Tokens: `packages/server/src/auth/api-token.ts`
- Email Verification: `packages/server/src/auth/email-verification.ts`
- Password Reset: `packages/server/src/auth/password-reset.ts`

### Testing (@guren/testing)
Source: `packages/testing/src/`

Included by default in `create-app`-scaffolded apps' `devDependencies`; if missing, `bun add -d @guren/testing`.

```typescript
import { TestApp } from '@guren/testing'

const app = await TestApp.create({
  auth: {},                      // mounts session + CSRF middleware (needed for withCsrf())
  routes: registerWebRoutes,
})

await app.get('/posts').assertOk()

const csrf = await app.actingAs(user).withCsrf()   // header auth + primed XSRF cookie
await csrf.post('/posts', { title: 'Hi' }).assertRedirect('/posts')
```

- `actingAs(user)` / `withCsrf()` each return a **new** `TestApp` — chain or reassign, don't discard the result
- Without `auth`, no session/CSRF middleware is mounted — `app.json().post(...)` skips CSRF entirely, fine for quick checks but not production-representative
- The main entry has no vitest dependency; DB lifecycle helpers (`useDatabaseTransactions` etc.) use bun:test globals automatically — vitest projects `import '@guren/testing/vitest'` once in setup to register hooks

## Extended Subsystems

### Authorization (Gate & Policy)
Source: `packages/server/src/authorization/`

- `Gate.ts` — Define abilities and policies
- `Policy.ts` — Resource-based authorization
- `middleware.ts` — Route-level authorization middleware

### Events & Listeners
Source: `packages/server/src/events/`

- `Event.ts` — Base event class
- `EventManager.ts` — Event dispatcher
- `Listener.ts` — Base listener class
- `builtin.ts` — Built-in framework events

Register listeners with `events.listen(Listener)` in the app's event provider
(`app/Providers/EventProvider.ts`), and list that provider in `createApp({ providers })`.

### Jobs & Queue
Source: `packages/server/src/queue/`

- `Job.ts` — Base job class with `handle()` method
- `QueueManager.ts` — Queue manager (memory, Redis drivers)
- `Worker.ts` — Queue worker process

Drivers: `packages/server/src/queue/drivers/`

### Mail
Source: `packages/server/src/mail/`

- `Mail.ts` — Base mailable class
- `MailManager.ts` — Mail manager

Transports:
- `MemoryTransport.ts` — For testing
- `ResendTransport.ts` — Resend API
- `SmtpTransport.ts` — SMTP

### Cache
Source: `packages/server/src/cache/`

- `CacheManager.ts` — Cache manager
- `TaggedCache.ts` — Tag-based cache invalidation

Stores:
- `MemoryStore.ts` — In-memory
- `FileStore.ts` — File-based
- `RedisStore.ts` — Redis

### Validation
Source: `packages/server/src/http/validation/`

- `Validator.ts` — Validation engine
- `rules.ts` — Built-in validation rules
- `FormRequest.ts` — Form request validation (`packages/server/src/http/FormRequest.ts`)

### Broadcasting
Source: `packages/server/src/broadcasting/`

- `BroadcastManager.ts` — Broadcast manager

Channels: `Channel.ts`, `PrivateChannel.ts`, `PresenceChannel.ts`
Drivers: `MemoryDriver.ts`, `RedisDriver.ts`

### Notifications
Source: `packages/server/src/notifications/`

- `Notification.ts` — Base notification class
- `NotificationManager.ts` — Notification dispatcher

Channels: `MailChannel.ts`, `SlackChannel.ts`, `DatabaseChannel.ts`, `MemoryChannel.ts`

### Storage
Source: `packages/server/src/storage/`

- `StorageManager.ts` — Storage manager

Drivers: `LocalDriver.ts`, `MemoryDriver.ts`, `S3Driver.ts`. On Cloudflare Workers, `R2Driver` from `@guren/plugin-cloudflare` (bucket binding; register with `storage.registerDisk()`).

### Scheduling
Source: `packages/server/src/scheduling/`

- `Schedule.ts` — Schedule definition
- `Scheduler.ts` — Scheduler runner
- `ScheduledTask.ts` — Individual scheduled task
- `CronParser.ts` — Cron expression parser

### I18n (Internationalization)
Source: `packages/server/src/i18n/`

- `I18nManager.ts` — I18n manager
- `Translator.ts` — Translation engine
- `pluralization.ts` — Pluralization rules

Loaders: `JsonLoader.ts`, `MemoryLoader.ts`

App wiring: `createApp({ i18n: { supported: ['en', 'ja'] } })` loads
`lang/<locale>/*.json`, mounts locale detection (query → cookie →
Accept-Language), and shares the `_i18n` prop with Inertia pages.
Translate with `this.t()` / `this.tc()` / `this.locale` in controllers and
`useTranslation()` from `@guren/inertia-client` in pages. `guren codegen`
emits typed keys (`.guren/translations.gen.ts`); `guren check --i18n`
validates catalog parity and placeholders.

### Encryption
Source: `packages/server/src/encryption/`

- `Encrypter.ts` — Encrypt/decrypt values
- `Hash.ts` — Hashing utilities
- `Random.ts` — Secure random generation

### Health Checks
Source: `packages/server/src/health/`

- `HealthManager.ts` — Health check manager
- `HealthCheck.ts` — Base health check

Checks: `DatabaseCheck.ts`, `RedisCheck.ts`, `CacheCheck.ts`, `MemoryCheck.ts`, `StorageCheck.ts`, `CustomCheck.ts`

### Error Handling
Source: `packages/server/src/errors/`

- `ExceptionHandler.ts` — Global exception handler (supports duck-typed `statusCode` property)
- `HttpException.ts` — Base HTTP exception
- `debug-page.ts` — Debug error page

Exceptions: `NotFoundHttpException.ts`, `ValidationException.ts`, `AuthenticationException.ts`, `AuthorizationException.ts`, `MethodNotAllowedException.ts`

The ExceptionHandler automatically handles:
- `HttpException` subclasses → uses their status code
- Any error with a `statusCode` property (duck-typed) → uses that status code (e.g., `ModelNotFoundException` → 404)
- Other errors → 500 (message hidden unless debug mode)

Factory methods — throw directly from a controller method, no try/catch needed:

```typescript
HttpException.badRequest(msg?)      // 400
HttpException.unauthorized(msg?)    // 401
HttpException.forbidden(msg?)       // 403
HttpException.notFound(msg?)        // 404
HttpException.conflict(msg?)        // 409
HttpException.unprocessable(msg?, errors?)  // 422 — same errors shape as validateBody()
HttpException.internal(msg?)        // 500
// also: methodNotAllowed / gone / tooManyRequests / notImplemented / badGateway / serviceUnavailable / gatewayTimeout

new ValidationException({ email: ['Already registered'] })          // 422
ValidationException.withMessages({ email: 'Already registered' })   // string | string[] values

new AuthenticationException(message?, guard?, redirectTo?)          // 401
AuthenticationException.withRedirect(redirectTo, message?)

new AuthorizationException(message?, action?, resource?)            // 403
AuthorizationException.deny(resource?)              // e.g. AuthorizationException.deny('Comment')
AuthorizationException.forAction(action, resource?)

new NotFoundHttpException(message?)                                 // 404
NotFoundHttpException.forModel('User', 123)
```

`Model.findOrFail()` throws `ModelNotFoundException` (exported from `@guren/core`) — it does *not* extend `HttpException`; the handler picks it up via its duck-typed `statusCode: 404`.

### Container & Service Providers
Source: `packages/server/src/container/`

- `Container.ts` — IoC container
- `ServiceProvider.ts` — Base service provider

Built-in providers: `packages/server/src/providers/`

### Console Commands
Source: `packages/server/src/console/`

- `Command.ts` — Base command class
- `ConsoleKernel.ts` — Console kernel
- `Input.ts` / `Output.ts` — IO handling

### API Resources
Source: `packages/server/src/http/resources/`

- `Resource.ts` — API resource transformer
- `ResourceCollection.ts` — Collection of resources
- `Paginator.ts` — Offset-based pagination
- `CursorPaginator.ts` — Cursor-based pagination

### Database (Factory & Seeder)
Source: `packages/server/src/database/`

- `Factory.ts` — Model factory for testing
- `Seeder.ts` — `BaseSeeder`/`Seeder`, deprecated in 2.9.0 (removed in 3.0.0)
- `SeederRunner.ts` — deprecated in 2.9.0 (removed in 3.0.0), wired to no command

Seeding itself does not live here. `db:seed` runs every seeder in `db/seeders/`,
and seeders are written with `defineSeeder` from `@guren/core`.

### Logging
Source: `packages/server/src/logging/`

- `LogManager.ts` — Log manager
- `Logger.ts` — Logger instance

Channels: `ConsoleChannel.ts`, `FileChannel.ts`, `DailyFileChannel.ts`

### Redis
Source: `packages/server/src/redis/`

- `client.ts` — Redis client
- Session, rate-limit, API token, email verification, password reset stores

## Reference Locations

| Subsystem | Source Path |
|-----------|------------|
| Controllers | `packages/server/src/mvc/Controller.ts` |
| Models | `packages/orm/src/Model.ts` |
| Routes | `packages/server/src/mvc/Route.ts` |
| Auth | `packages/server/src/auth/` |
| Testing | `packages/testing/src/` |
| Authorization | `packages/server/src/authorization/` |
| Events | `packages/server/src/events/` |
| Queue/Jobs | `packages/server/src/queue/` |
| Mail | `packages/server/src/mail/` |
| Cache | `packages/server/src/cache/` |
| Validation | `packages/server/src/http/validation/` |
| Broadcasting | `packages/server/src/broadcasting/` |
| Notifications | `packages/server/src/notifications/` |
| Storage | `packages/server/src/storage/` |
| Scheduling | `packages/server/src/scheduling/` |
| I18n | `packages/server/src/i18n/` |
| Encryption | `packages/server/src/encryption/` |
| Health Checks | `packages/server/src/health/` |
| Error Handling | `packages/server/src/errors/` |
| Container | `packages/server/src/container/` |
| Console | `packages/server/src/console/` |
| API Resources | `packages/server/src/http/resources/` |
| Database/Seeder | `packages/server/src/database/` |
| Logging | `packages/server/src/logging/` |
| Redis | `packages/server/src/redis/` |
| Example App | `examples/blog/` |
| API Example | `examples/api/` |
| Docs | `web/` |

Attribution

gurenjsgurenjs
View sourceMore from gurenjs →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

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 (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284072 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2192 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →