Skip to content

Commit ecb1309

Browse files
committed
feat: introduce CredentialRecord and update references from PublicKeyCredentialSource
1 parent f134fec commit ecb1309

File tree

58 files changed

+4458
-157
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+4458
-157
lines changed

.ci-tools/phpstan-baseline.neon

Lines changed: 1788 additions & 30 deletions
Large diffs are not rendered by default.

CLAUDE.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is a FIDO2/WebAuthn framework for PHP and Symfony, implementing the W3C WebAuthn specification. The repository contains three complementary modules organized as a monorepo:
8+
9+
- **webauthn-lib** (`src/webauthn/`) - Core PHP library with no framework dependencies
10+
- **webauthn-symfony-bundle** (`src/symfony/`) - Symfony integration providing controllers, services, and configuration
11+
- **webauthn-stimulus** (`src/stimulus/`) - Frontend Stimulus.js integration for client-side WebAuthn interactions
12+
13+
## Development Commands
14+
15+
### PHP Development (via Castor)
16+
17+
The project uses Castor for task automation. Commands use the `castor` CLI:
18+
19+
```bash
20+
# Run all tests with coverage
21+
castor phpunit
22+
23+
# Static analysis
24+
castor phpstan
25+
castor phpstan:baseline # Generate new baseline
26+
27+
# Code style
28+
castor ecs # Check coding standards
29+
castor ecs:fix # Auto-fix coding standards
30+
31+
# Refactoring
32+
castor rector # Check refactoring suggestions
33+
castor rector:fix # Apply refactoring
34+
35+
# Architecture validation
36+
castor deptrac # Check dependency layers
37+
38+
# Syntax checking
39+
castor lint
40+
41+
# Mutation testing
42+
castor infect
43+
44+
# License compliance
45+
castor check-licenses
46+
47+
# Prepare code for PR (fixes style, applies Rector, runs analysis)
48+
castor prepare-pr
49+
```
50+
51+
### JavaScript Development
52+
53+
```bash
54+
# Run all JavaScript tests
55+
npm test
56+
57+
# Linting
58+
npm run lint # Check linting
59+
npm run lint:fix # Auto-fix linting issues
60+
61+
# Code formatting
62+
npm run format # Check formatting
63+
npm run format:fix # Auto-fix formatting
64+
```
65+
66+
### Running Single Tests
67+
68+
PHPUnit tests are located in:
69+
- `tests/framework/` - Core library tests
70+
- `tests/library/` - Additional library tests
71+
- `tests/symfony/functional/` - Symfony bundle functional tests
72+
- `tests/MDS/` - Metadata Service tests
73+
74+
To run specific tests, use the standard PHPUnit filter syntax via the vendor binary:
75+
```bash
76+
vendor/bin/phpunit --filter=TestClassName tests/
77+
vendor/bin/phpunit tests/framework/SomeSpecificTest.php
78+
```
79+
80+
## Architecture Overview
81+
82+
### Ceremony Steps Pattern
83+
84+
The core validation logic uses a "ceremony steps" pattern where both registration and authentication ceremonies are composed of discrete, reusable validation steps:
85+
86+
- Steps are located in `src/webauthn/src/CeremonyStep/`
87+
- Each step implements the `CeremonyStep` interface
88+
- Steps are orchestrated by `CeremonyStepManager` (built via `CeremonyStepManagerFactory`)
89+
- Registration ceremony includes ~14 steps (CheckOrigin, CheckChallenge, CheckRelyingPartyIdHash, etc.)
90+
- Authentication ceremony includes ~12 steps (CheckSignature, CheckCounter, CheckUserHandle, etc.)
91+
92+
### Main Validators
93+
94+
Two primary validators orchestrate the ceremony flows:
95+
96+
- `AuthenticatorAttestationResponseValidator` - Handles registration/attestation
97+
- `AuthenticatorAssertionResponseValidator` - Handles authentication/assertion
98+
99+
Both validators:
100+
- Use `CeremonyStepManager` to run validation steps
101+
- Support PSR-14 event dispatching for extensibility
102+
- Support PSR-3 logging
103+
- Update credential records with final authenticator data after successful validation
104+
105+
### Repository Pattern
106+
107+
Data persistence is abstracted through repository interfaces:
108+
109+
- `CredentialRecordRepositoryInterface` - Query credentials by user or credential ID
110+
- Optional `CanSaveCredentialRecord` interface for persistence operations
111+
- `PublicKeyCredentialUserEntityRepositoryInterface` - User lookup by username or user handle
112+
- Implementations: `DoctrineCredentialSourceRepository` (Doctrine), `DummyCredentialRecordRepository` (testing)
113+
114+
### Core Data Models
115+
116+
Key entities that represent WebAuthn protocol data:
117+
118+
**Options (sent to client):**
119+
- `PublicKeyCredentialCreationOptions` - Registration ceremony options
120+
- `PublicKeyCredentialRequestOptions` - Authentication ceremony options
121+
122+
**Responses (received from client):**
123+
- `AuthenticatorAttestationResponse` - Registration response with attestationObject
124+
- `AuthenticatorAssertionResponse` - Authentication response with signature
125+
126+
**Stored Credentials:**
127+
- `CredentialRecord` - Server-side representation of a credential (credential ID, public key, counter, backup status, etc.)
128+
- `PublicKeyCredentialUserEntity` - User information
129+
- `PublicKeyCredentialRpEntity` - Relying Party information
130+
131+
**Supporting Data:**
132+
- `CollectedClientData` - Parsed clientDataJSON (challenge, origin, type)
133+
- `AuthenticatorData` - Parsed authenticator data (RP ID hash, flags, counter, extensions)
134+
- `AttestationObject` - Contains attestation statement and authenticator data
135+
136+
### Ceremony Flows
137+
138+
**Registration (Attestation):**
139+
1. Client calls `/attestation/request` → server generates `PublicKeyCredentialCreationOptions`
140+
2. Options stored in session/cache, returned to client
141+
3. Client uses WebAuthn API to create credential
142+
4. Client posts response to `/attestation/response`
143+
5. Server validates via `AuthenticatorAttestationResponseValidator.check()` using ceremony steps
144+
6. If valid, credential persisted via repository
145+
146+
**Authentication (Assertion):**
147+
1. Client calls `/assertion/request` → server generates `PublicKeyCredentialRequestOptions`
148+
2. Options stored in session/cache, returned to client
149+
3. Client uses WebAuthn API to get credential
150+
4. Client posts response to `/assertion/response`
151+
5. Server validates via `AuthenticatorAssertionResponseValidator.check()` using ceremony steps
152+
6. If valid, credential record updated with new counter and backup status
153+
154+
### Symfony Bundle Integration
155+
156+
Located in `src/symfony/`:
157+
158+
**Controllers:**
159+
- `AttestationRequestController`, `AttestationResponseController` - Handle registration
160+
- `AssertionRequestController`, `AssertionResponseController` - Handle authentication
161+
- Controllers use factory pattern (`AttestationControllerFactory`, `AssertionControllerFactory`)
162+
163+
**Configuration:**
164+
- Service definitions in `src/symfony/src/Resources/config/`
165+
- Doctrine mappings in `src/symfony/src/Resources/config/doctrine-mapping/`
166+
- Bundle configuration via `Configuration.php`
167+
168+
**Security Integration:**
169+
- `WebauthnAuthenticator` - Symfony security authenticator
170+
- `WebauthnToken` - Authentication token
171+
- Event system for security events
172+
173+
### Options Builders & Handlers
174+
175+
**Options Building:**
176+
- `PublicKeyCredentialCreationOptionsBuilder` - Interface for building creation options
177+
- `ProfileBasedCreationOptionsBuilder` - Profile-driven implementation
178+
- `PublicKeyCredentialCreationOptionsFactory` - Factory with configured settings
179+
180+
**Success/Failure Handlers:**
181+
- Provide extensible hooks for custom post-validation logic
182+
- `SuccessHandler`/`FailureHandler` interfaces with default implementations
183+
- Used by controllers to handle ceremony outcomes
184+
185+
### Recent Architectural Changes
186+
187+
The codebase recently underwent a significant refactoring (visible in recent commits):
188+
- `PublicKeyCredentialSource` renamed to `CredentialRecord`
189+
- `PublicKeyCredentialSourceRepository` renamed to `CredentialRecordRepository`
190+
- This improves clarity about what the entity represents (a record of a credential, not the credential itself)
191+
192+
## PHP Requirements
193+
194+
- PHP >= 8.2
195+
- Extensions: json, openssl
196+
- Symfony 6.4+ or 7.0+
197+
198+
## Testing Philosophy
199+
200+
- Tests are in `tests/` directory with subdirectories for each module
201+
- PHPUnit configuration at `.ci-tools/phpunit.xml.dist`
202+
- Mutation testing via Infection for quality assurance
203+
- Functional tests for Symfony bundle integration
204+
- JavaScript tests using Jest
205+
206+
## CI/CD Pipeline
207+
208+
GitHub Actions workflow (`.github/workflows/ci.yml`) runs:
209+
1. Pre-checks (file permissions, ASCII characters)
210+
2. PHPStan (static analysis)
211+
3. ECS (coding standards)
212+
4. Rector (refactoring checks)
213+
5. Composer validation
214+
6. Syntax checking
215+
7. License compliance
216+
8. Deptrac (architecture validation)
217+
9. PHPUnit tests (PHP 8.2, 8.3, 8.4)
218+
10. JavaScript lint, format, and tests
219+
11. Mutation testing (on release branches)
220+
221+
## Documentation
222+
223+
Full documentation available at: https://webauthn-doc.spomky-labs.com/
224+
225+
## Important Notes
226+
227+
- Main branch for PRs: `5.3.x` (or current version branch, not `main`)
228+
- This is a monorepo that replaces separate packages via `composer.json` `replace` section
229+
- Security vulnerabilities should be reported via GitHub Security Advisory, not public issues
230+
- Recent refactoring renamed `PublicKeyCredentialSource` to `CredentialRecord` - be aware when working with older code or documentation

0 commit comments

Comments
 (0)