Skip to content
Back to skills

Spring Security Baseline

ASecurity

Minimum Spring Security 7 configuration patterns and review baseline. Use when designing or reviewing authentication, authorization, CSRF, CORS, secrets handling, or input validation.

  • 62 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
developmentrustjavasqlspringcode-reviewapisecurity

Works with

  • cli
  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add loiane/specs-driven-development-spring-angular --skill spring-security-baseline --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Spring Security Baseline?

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

Security grade badge for Spring Security Baseline
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/loiane-spring-security-baseline/badge)](https://www.skillsdirectory.com/skills/loiane-spring-security-baseline)

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: spring-security-baseline
description: Minimum Spring Security 7 configuration patterns and review baseline. Use when designing or reviewing authentication, authorization, CSRF, CORS, secrets handling, or input validation.
when_to_use:
  - Phase 3 (Plan) — designing auth/authz for an endpoint.
  - Phase 7 (Code review) — security rubric of `08-code-review.md`.
authoritative_references:
  - https://docs.spring.io/spring-security/reference/index.html
  - https://owasp.org/Top10/
---

# Spring Security baseline

## What every endpoint must declare

In `03-design.md`, for each new/changed endpoint:

- **AuthN**: Anonymous? Bearer (JWT)? Session? mTLS?
- **AuthZ**: What role/scope/claim is required?
- **Input validation**: Bean Validation on the DTO (`@NotNull`, `@Size`, `@Pattern`, …) PLUS service-layer invariants.
- **Output**: Does the response include any field the caller is not allowed to see?
- **Audit**: Should this action be logged with structured fields (`actor`, `subject`, `outcome`)?

If any of these is unclear, write a `Q-NNN` — do not pick a default.

## Default `SecurityFilterChain` (resource server, JWT)

```java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
class SecurityConfig {

    @Bean
    SecurityFilterChain api(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/api/**")
            .authorizeHttpRequests(a -> a
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated())
            .oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults()))
            .csrf(csrf -> csrf.disable())                // stateless API
            .sessionManagement(s -> s.sessionCreationPolicy(STATELESS))
            .headers(h -> h
                .contentSecurityPolicy(c -> c.policyDirectives("default-src 'none'"))
                .referrerPolicy(r -> r.policy(STRICT_ORIGIN_WHEN_CROSS_ORIGIN)));
        return http.build();
    }
}
```

CSRF is **disabled only for stateless APIs**. If sessions are used, CSRF is on.

## Method-level authorization

Prefer `@PreAuthorize` with SpEL using JWT claims:

```java
@PreAuthorize("hasAuthority('SCOPE_orders:write') and #orderId == authentication.token.claims['order_id']")
public Order apply(@PathVariable UUID orderId, @Valid @RequestBody ApplyGiftCardRequest req) { ... }
```

## Secrets

- **Never** commit secrets. Use environment variables or a secrets manager.
- `application.yml` references `${VAR}`; absence fails fast at startup.
- Tests use Testcontainers; secrets there are throwaway.

## Input validation

Two layers:

1. **Boundary** — Bean Validation on DTO + `@Valid` on controller method.
2. **Service** — re-check invariants that depend on the entity state (e.g. "card not yet redeemed" is a service-layer check, not a DTO check).

Never trust client-supplied IDs. Always re-resolve to a domain object scoped by the caller.

## Logging & observability

- Log security events at `INFO` with structured key/values: `actor=<sub>`, `action=apply_gift_card`, `outcome=denied`, `reason=card_redeemed`.
- Never log PII, secrets, full JWT, full card number. Mask: `code=ABC***`.

## Review rubric (used by code-reviewer)

- [ ] No endpoint without an explicit `requestMatchers` decision (default-deny).
- [ ] No `permitAll()` on a state-changing endpoint.
- [ ] No `@PreAuthorize` SpEL referencing user-supplied data unchecked.
- [ ] No `@CrossOrigin("*")` in production code.
- [ ] No raw SQL with string concatenation.
- [ ] No reflective bean access on user input.
- [ ] No `@JsonProperty` exposing internal entity fields.
- [ ] CSRF state matches whether the API is stateful.
- [ ] Sensitive data is masked in logs.
- [ ] OWASP Dependency Check has no new High/Critical CVEs (or one waiver per CVE in `dependency-check-suppressions.xml`).

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.