OpenAPI Development Guide
This guide documents the development process for creating and maintaining the cyber.trackr.live OpenAPI specification.
Development Approach
1. Discovery Phase
We started by exploring the API to understand its structure:
# Discover API root
curl -sL -H "Accept: application/json" "https://cyber.trackr.live/api/" | jq .
# Count resources
curl -sL "https://cyber.trackr.live/api/stig" | jq 'keys | length' # 1032 STIGs/SRGs
# Explore specific endpoints
curl -sL "https://cyber.trackr.live/api/stig/Juniper_SRX_Services_Gateway_ALG/3/3" | jq 'keys'
2. Schema Development
We built schemas by examining actual API responses:
# Example: Building RequirementDetail schema from API response
RequirementDetail:
type: object
required:
- id
- rule
- severity
- requirement-title
- check-text
- fix-text
properties:
id:
type: string
pattern: '^V-\d{6}$'
example: "V-214518"
# ... etc
3. Iterative Refinement
The spec was refined through multiple iterations:
- Initial draft - Basic endpoints and schemas
- Add missing endpoints - SCAP, RMF list endpoints
- Fix OpenAPI 3.1 syntax - Nullable fields, example vs examples
- Document actual behavior - 500 errors for invalid parameters
OpenAPI 3.1.1 Specific Features
Nullable Fields
OpenAPI 3.1 uses JSON Schema 2020-12 syntax:
# WRONG - OpenAPI 3.0 style
mitigation-statement:
type: ['string', 'null']
# CORRECT - OpenAPI 3.1 style
mitigation-statement:
anyOf:
- type: string
- type: "null"
Examples
For single values use example
, for arrays use example
(not examples
):
# Single value
severity:
type: string
example: "medium"
# Array value
identifiers:
type: array
example: ["V-66003", "SV-80493", "CCI-000213"]
Testing Philosophy
Test-Driven Documentation
We use tests to drive documentation accuracy:
- Write test for expected behavior
- Run against real API
- Update spec to match reality
- Verify with tests
Example discovering 500 vs 404 behavior:
# Expected behavior (failed)
assert_equal 404, response.status, "Invalid V-ID should return 404"
# Actual behavior (updated)
assert_equal 500, response.status, "Invalid V-ID should return 500"
Ruby-First Testing
We chose Ruby-based testing tools over JavaScript alternatives:
openapi3_parser
- Ruby gem for OpenAPI validationminitest
- Simple, effective test frameworkfaraday
- Flexible HTTP client
Benefits:
- No Node.js dependency
- Consistent with InSpec project
- Better integration with Ruby client
Schema Design Patterns
Shared Schemas
Common structures are defined once and referenced:
# Document listing pattern used by STIG and SCAP
DocumentList:
type: object
additionalProperties:
type: array
items:
$ref: '#/components/schemas/DocumentVersion'
Consistent Patterns
Parameter patterns are defined consistently:
# Used across all endpoints
'^V-\d{6}$' # V-IDs
'^CCI-\d{6}$' # CCI-IDs
'^[A-Z]+-\d+$' # RMF controls
API Quirks and Workarounds
Mixed STIG/SRG Endpoint
The /stig
endpoint returns both STIGs and SRGs. We document this clearly:
description: |
Returns complete list of Security Technical Implementation Guides (STIGs) and
Security Requirements Guides (SRGs). **Note**: These are mixed in one endpoint.
Use document name patterns to distinguish:
- SRGs contain "Security_Requirements_Guide" or "(SRG)" in name
- STIGs are vendor/product specific
Error Response Inconsistency
Invalid parameters return 500 instead of 404. We document this in:
- Endpoint responses
- Test assertions
- README notes
Validation Strategy
Three-Layer Validation
- Syntax - Valid OpenAPI 3.1.1 structure
- Completeness - All endpoints/schemas present
- Accuracy - Matches real API behavior
Continuous Validation
# Quick check after changes
ruby test/openapi_validation_test.rb
# Full validation before commits
./run_all_tests.sh
Future Improvements
Potential Enhancements
- Add more examples - Real data for each schema
- Expand descriptions - More detail on field meanings
- Add x-extensions - Custom metadata for tooling
- Response time documentation - Note slow endpoints
Schema Evolution
As the API evolves:
- Monitor for new endpoints
- Check for schema changes
- Update parameter patterns
- Test error behaviors
Tools and Resources
Development Tools
- VS Code - YAML syntax highlighting
- Swagger Editor - Visual validation (use carefully with 3.1)
- jq - JSON exploration
- curl - API testing
References
Lessons Learned
- Test against real API early - Assumptions often wrong
- Document actual behavior - Even if non-ideal
- Use consistent patterns - Makes spec maintainable
- Validate continuously - Catch issues quickly
- Ruby tools are sufficient - No need for Node.js ecosystem