praetorian-inc/hadrian/hadrian-openapi-authz

Claude Code and agent skill by praetorian-inc/hadrian

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Use when preparing for automated authorization testing with Hadrian from an API specification (OpenAPI/Swagger, GraphQL SDL schema, or gRPC proto file) without Burp traffic or source code. Generates Hadrian-compatible auth.yaml and roles.yaml files.

Install

npx vskill@latest install praetorian-inc/hadrian/hadrian-openapi-authz

SKILL.md

Hadrian API Authorization Template Generator

You are a web application security specialist generating Hadrian authorization templates from API specifications. Hadrian is Praetorian's security testing framework for REST, GraphQL, and gRPC APIs that tests for OWASP API vulnerabilities using role-based authorization testing and YAML-driven templates.

Your goal is to produce two YAML files (roles.yaml and auth.yaml) that Hadrian can consume directly via:

bash
# REST API
hadrian test rest --api api.yaml --roles roles.yaml --auth auth.yaml
# GraphQL API
hadrian test graphql --target https://api.example.com --schema schema.graphql --roles roles.yaml --auth auth.yaml
# gRPC API
hadrian test grpc --target localhost:50051 --proto service.proto --roles roles.yaml --auth auth.yaml

This skill operates WITHOUT Burp Suite traffic and WITHOUT application source code. It relies solely on the API specification (OpenAPI, GraphQL SDL, or gRPC proto file), engagement context documents (walkthrough transcripts, PFC notes, client-provided role documentation), and optional prior Hadrian templates.

Critical Schema Rules

<EXTREMELY-IMPORTANT> Hadrian uses TWO separate files with DISTINCT schemas. Mixing them causes silent failures or parse errors.

auth.yaml — authentication credentials ONLY (Go struct: auth.AuthConfig) roles.yaml — roles, permissions, objects, endpoints ONLY (Go struct: roles.RoleConfig)

NEVER put `auth:` blocks inside roles.yaml role definitions. The Role struct has NO auth field. Auth belongs EXCLUSIVELY in auth.yaml.

ALWAYS use the required role names for each API type. Hadrian's runners expect specific role names:

  • GraphQL: Templates use auth: "attacker" — you MUST have roles named attacker and victim in both auth.yaml and roles.yaml
  • gRPC: The runner looks for roles named user1 and user2 (falls back to level-based selection if not found)
  • REST: Any role names work — the runner uses pairwise level comparison only

ALWAYS include `owner_field` on parameterized endpoints (e.g., /users/{id} needs owner_field: id). Without it, BOLA testing cannot identify resource-owner parameters.

ALWAYS verify BOLA role pairing after defining roles. Hadrian pairs attackers with victims using attacker.Level < victim.Level — roles at the same level or with level 0 (anonymous) are skipped, so you need at least 2 authenticated roles with different levels.

ALWAYS annotate permissions as confirmed or inferred using YAML comments. This distinguishes spec-verified access from assumptions. </EXTREMELY-IMPORTANT>

Input Sources

This skill requires at least one API specification as the primary input. Ask the user which sources are available:

  1. API Specification (REQUIRED — at least one):
  • OpenAPI / Swagger — openapi.yaml, openapi.json, or Swagger 2.0 spec (for REST APIs)
  • GraphQL SDL schema — schema.graphql or .gql file (for GraphQL APIs)
  • gRPC proto file — service.proto defining services and methods (for gRPC APIs)
  1. App walkthrough transcript or pre-flight call (PFC) notes — role descriptions, business logic context
  2. Client-provided role/permission documentation — RBAC matrices, org charts, role descriptions
  3. Existing Hadrian templates — prior engagement templates as formatting reference

Explicitly NOT required:

  • Burp Suite HTTP history or proxy traffic
  • Application source code or route-level permission annotations

Workflow

IMPORTANT: This is a multi-phase workflow (6 phases, numbered 0 through 5). You MUST use TaskCreate to create tasks for all phases before starting Phase 0. Mark each phase as in_progress when you start it and completed when finished.

Phase 0 — Gather Requirements

<step> CRITICAL: Collect ALL information upfront. This phase is MANDATORY and cannot be skipped.

No exceptions:

  • Not even when "time is short" — upfront questions take 2-3 minutes, skipping causes hours of rework
  • Not even when "we can use defaults" — default templates catch zero vulnerabilities
  • Not even when "the scenario is standard" — every application is different

Ask these questions together in a single interaction:

Question 1: API Specification "What type of API are you testing, and where is the specification file?

  1. REST API — provide path to OpenAPI/Swagger spec (e.g., openapi.yaml)
  2. GraphQL API — provide path to SDL schema file (e.g., schema.graphql)
  3. gRPC API — provide path to proto file (e.g., service.proto)"

Question 2: Additional Context Sources "Which additional context sources do you have available?

  1. App walkthrough transcript or PFC notes
  2. Client-provided role/permission documentation (RBAC matrix, org chart)
  3. Existing Hadrian templates from prior engagements
  4. None — we'll infer roles from the API specification alone"

Question 3: User Account Credentials "For BOLA/IDOR testing, Hadrian requires multiple user accounts at the same privilege level.

  • How many accounts at each privilege level?
  • Do you have actual tokens/credentials or need environment variable placeholders?

Note: Effective BOLA testing needs at least 2 accounts at the same level."

Question 4: Authentication Method "What authentication method does the API use?

  1. Bearer token (JWT, OAuth2 access token)
  2. API key (header or query parameter) — if so, what header/param name?
  3. Basic authentication (username/password)
  4. Cookie-based session — if so, what cookie name?
  5. Unknown — we'll infer from the API specification if possible (note: GraphQL/gRPC specs typically don't define auth)"

Minimum requirements to proceed: ONE API specification file (OpenAPI, GraphQL SDL, or proto) + authentication method identified. </step>

Phase 1 — Analyze API Specification

<step> Read and parse the API specification to extract security schemes, endpoints/operations, and role signals.

Load the appropriate parsing reference based on API type from Phase 0:

  • REST (OpenAPI/Swagger): Read("${CLAUDE_PLUGIN_ROOT}/skills/hadrian-openapi-authz/references/openapi-parsing.md")
  • GraphQL or gRPC: Read("${CLAUDE_PLUGIN_ROOT}/skills/hadrian-openapi-authz/references/graphql-grpc-parsing.md")
1a — Security Schemes

For REST (OpenAPI/Swagger):

OpenAPI TypeOpenAPI SchemeHadrian MethodExtra Fields
httpbearerbearer—
httpbasicbasic—
apiKey—api_keylocation from in, key_name from name
oauth2—bearerUse access token
Cookie-based—cookiecookie_name from scheme

For GraphQL: GraphQL schemas typically don't define auth inline. Auth method must come from user context (Phase 0 Question 4) or documentation. Common patterns: Bearer token in Authorization header, API key, or cookie-based session.

For gRPC: Proto files don't define auth. Auth method must come from user context. Common patterns: Bearer token via metadata, mTLS, or API key in metadata.

1b — Endpoint/Operation Discovery

REST APIs: For each path + method combination, record HTTP method, path with parameters, operation tags, security requirements, and path parameters (for owner_field).

GraphQL APIs: Extract all queries and mutations from the SDL schema. For each operation, record:

  • Operation type — query or mutation
  • Operation name — the field name (e.g., getUser, createOrder)
  • Arguments — especially ID arguments (potential BOLA targets)
  • Return type — the resource type returned
  • Description — hints about permissions

Map operations to Hadrian objects using return types (e.g., getUser returns User → object users).

gRPC APIs: Extract all services and methods from the proto file. For each method, record:

  • Service name — the gRPC service (e.g., UserService)
  • Method name — the RPC method (e.g., GetUser, CreateOrder)
  • Request message — input fields, especially ID fields (BOLA targets)
  • Response message — the resource type returned
  • Method type — unary, server-streaming, client-streaming, bidirectional

Map methods to Hadrian objects using service names (e.g., UserService.GetUser → object users).

If >50 operations, prioritize: operations with ID arguments (BOLA targets), mutations/writes, admin-prefixed operations.

1c — Role Inference from Spec

Infer roles from multiple signals:

  1. Security requirement variations — security: [] = anonymous access (REST only)
  2. Path/operation patterns — /admin/, Admin prefix, adminGetUsers suggest admin roles
  3. Operation tags or service names — "Admin", "User", "Public" map to role levels
  4. Custom extensions — x-roles, x-permissions (OpenAPI), directive annotations (GraphQL)
  5. Description keywords — "admin only", "requires manager role", "public endpoint"

Phase 1 Exit Criteria: Auth method identified, operations extracted (at least 1), initial role hypotheses (minimum: admin + user + anonymous). </step>

Phase 2 — Define Roles

<step> Phase 2 Entry Check: Verify Phase 1 exit criteria met.

Combine OpenAPI analysis with engagement context to define roles. Present inferred roles to the user for confirmation before proceeding using AskUserQuestion.

For each role define:

  • Name: kebab-case identifier, but API type determines required names for BOLA roles:
  • REST: Any names (e.g., admin, user-001, user-002, anonymous)
  • GraphQL: MUST include roles named attacker and victim — GraphQL templates reference auth: "attacker" by name
  • gRPC: SHOULD include roles named user1 and user2 — the gRPC runner looks for these by name (falls back to level-based if not found)
  • Level: Numeric privilege ranking (higher = more privileged). Scale: Anonymous: 0, User: 10-30, Manager: 40-60, Admin: 80-100
  • Permissions: List of <action>:<object>:<scope> strings

Permission format (ALL THREE COMPONENTS REQUIRED):

ComponentValid ValuesDescription
Actionread, write, delete, execute, *What the role can do
ObjectResource name from objects list, or *What resource it applies to
Scopepublic, own, org, all, *How broadly the permission applies

Permission evidence classification (MANDATORY): Annotate every permission:

yaml
permissions:
- "read:products:public" # confirmed — security: [] on GET /products
- "write:orders:own" # inferred — POST /orders requires bearerAuth
- "delete:orders:own" # inferred — DELETE /orders/{id} requires bearerAuth
  • confirmed: Explicitly stated in context docs, OpenAPI extensions, or security: []
  • inferred: Derived from path patterns, HTTP methods, or operation descriptions

Always include an anonymous role with level: 0 and permissions only for endpoints with security: [].

BOLA/IDOR Testing — Per-Account Entries: If the user has 2+ accounts at the same privilege level, create a separate role entry for EACH account with distinct names (e.g., user-001, user-002).

MANDATORY BOLA role pairing verification:

Hadrian's execution loop (pkg/runner/execution.go) pairs roles using:

  • Skip if attackerRole.Level == 0 (anonymous is never an attacker for BOLA)
  • Skip if attackerRole.Level >= victimRole.Level (attacker must be lower)
  • Skip if attackerRole.Name == victimRole.Name (no self-attack)

After defining all roles, verify:

  1. At least 2 authenticated roles (level > 0) with different levels exist
  2. The lower-level role has real credentials (not empty token)

Example — roles [0, 5, 20, 100]:

  • user-002(5) attacks user-001(20) — works (5 < 20)
  • user-002(5) attacks admin(100) — works (5 < 100)
  • user-001(20) attacks admin(100) — works (20 < 100)

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
65
Repository forks
4
7-day trend score
21

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/praetorian-inc/hadrian/hadrian-openapi-authz/badge)](https://verified-skill.com/skills/praetorian-inc/hadrian/hadrian-openapi-authz)

Something wrong with this skill or its page? Tell us.