Skip to content

appsecone

Python 3.12+Tests: 464 passedLicense: AGPL-3.0CIFastAPISource: Fortify SSCi18n: EN | PL

Enterprise-grade security posture dashboard that answers: "Are we ready to release?"
Fortify SSC . Policy Engine . Trend Analytics . Waiver Management . Release Readiness . i18n

About . Screenshots . Features . Installation . Quick Start . Configuration . API . Architecture . Testing

Support this project


What is AppSecOne?

AppSecOne is an enterprise application security dashboard that aggregates vulnerability data from Fortify SSC, evaluates release readiness through a deterministic policy engine, and presents the results in a real-time web dashboard with full API access.

Security teams, engineering managers, and release coordinators use it to answer critical questions every sprint:

  • "Can we ship this release?" - Policy engine evaluates every repository against configurable thresholds for critical, high, and medium findings.
  • "What's our security posture across the portfolio?" - Aggregated severity breakdowns, readiness scores, and trend analytics across all repositories.
  • "Are we improving or regressing?" - Historical trend snapshots with 5% threshold direction classification (improving / stable / worsening).
  • "Which teams need attention?" - Filter by team, repository type, criticality level, and readiness status.
  • "What did we waive, and why?" - Full waiver management with audit trail, expiry tracking, and approval workflows.

AppSecOne syncs from Fortify SSC on a configurable interval (default 30 minutes), stores a local read model in SQLite, and serves a server-rendered dashboard via FastAPI + Jinja2 - no JavaScript frameworks, no build steps, no external CSS dependencies.


Screenshots

Portfolio Dashboard

Aggregated severity breakdown, readiness donut chart, repository cards with status indicators, trend badges, and policy evaluation - all in a single overview.

AppSecOne - Portfolio dashboard with severity breakdown, readiness chart, and repository cards

Repository Detail

Deep-dive into a single repository - findings table with severity badges, policy evaluation with blocker panels, stacked severity bar, and historical trend chart.

AppSecOne - Repository detail with findings, policy evaluation, and trend chart


Features

Data Integration

  • Fortify SSC sync - periodic (30 min) and on-demand, with auto-pagination and retry
  • Full re-sync every 24 hours to catch deletions and metadata changes
  • Concurrent sync - up to 5 parallel project syncs for large portfolios
  • Local SQLite read model - fast queries, offline resilience, zero external DB dependencies

Policy Engine

  • Deterministic evaluation - pure functions, no side effects, fully testable
  • Configurable thresholds - max critical, max high, max medium per severity
  • Finding age limits - flag findings older than N days (e.g., 30 days for critical)
  • Named policy profiles - different rules for different criticality levels (e.g., strict for business-critical)
  • Waiver management - create, revoke, and track waivers with expiry and audit trail
  • Risk acceptance - configurable per policy profile

Dashboard & Presentation

  • Server-side rendered - Jinja2 templates with vanilla JS, no framework, no build step
  • Responsive layout - works on desktop, tablet, and mobile
  • 4 themes - light, dark, midnight, and system auto-detect
  • Custom design system - CSS custom properties for tokens, severities, and branding
  • Internationalization - full i18n with locale catalogs (English, Polish)
  • Accessibility - ARIA roles, focus-visible indicators, keyboard navigation, screen reader support
  • Export - findings to CSV/JSON, dashboard to standalone HTML

Analytics

  • Trend snapshots - daily aggregates for historical analysis
  • Direction classification - improving / stable / worsening with 5% threshold
  • Configurable period - 7 to 365 days of trend data

Operations

  • Health probes - Kubernetes-ready /health/live and /health/ready
  • SSE streaming - real-time sync progress via Server-Sent Events
  • Correlation IDs - end-to-end request tracing
  • Structured logging - JSON-ready, verbose mode via CLI flag

Table of Contents


Installation

Prerequisites

  • Python 3.12+
  • Access to a Fortify SSC instance (with a valid API token)

Install from source

git clone https://github.com/polprog-tech/AppSecOne.git
cd AppSecOne
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Install with dev dependencies

pip install -e ".[dev]"

Quick Start

1. Create your configuration file:

cp examples/config.json appsecone.json
cp examples/.env.example .env

2. Set your Fortify SSC token:

export FORTIFY_SSC_TOKEN=your-fortify-token-here

3. Validate the configuration:

appsecone validate --config appsecone.json

4. Run your first sync:

appsecone sync --config appsecone.json

5. Launch the dashboard:

appsecone serve --config appsecone.json

Open http://127.0.0.1:8090 in your browser.


Configuration

Configuration File (appsecone.json)

{
"fortify": {
"base_url": "https://fortify.corp.example.com/ssc",
"token_env_var": "APPSECONE_FORTIFY_TOKEN",
"timeout_seconds": 30,
"max_retries": 3,
"verify_ssl": true
},
"sync": {
"interval_minutes": 30,
"full_sync_interval_hours": 24,
"max_concurrent": 5,
"enabled": true
},
"policy": {
"max_critical": 0,
"max_high": 5,
"max_open_findings": null,
"max_age_days_critical": 30,
"max_age_days_high": 90,
"allow_risk_acceptance": true
},
"branding": {
"title": "AppSecOne",
"company": "Your Company",
"primary_color": "#fb6400"
},
"settings": {
"theme": "system",
"log_level": "info",
"host": "127.0.0.1",
"port": 8090
},
"repositories": [
{
"slug": "web-app",
"name": "WebApp",
"fortify_project_name": "Corp WebApp",
"type": "web",
"team": "platform",
"criticality": "high",
"layer": "frontend"
}
],
"policy_profiles": {
"strict": {
"max_critical": 0,
"max_high": 0,
"max_medium": 10,
"max_age_days_critical": 14,
"max_age_days_high": 30
}
}
}

Environment Variables

VariableDescriptionDefault
APPSECONE_FORTIFY_TOKENFortify SSC API token (required)-
APPSECONE_HOSTServer bind address127.0.0.1
APPSECONE_PORTServer bind port8090
APPSECONE_DEBUGEnable debug modefalse
APPSECONE_LOG_LEVELLog level (debug, info, warning, error)info
APPSECONE_API_KEYAPI key for admin endpoints (optional)-
APPSECONE_ALLOW_FRAMINGAllow embedding in iframesfalse
APPSECONE_CORS_ORIGINSAllowed CORS origins (comma-separated)-
HTTP_PROXYCorporate HTTP proxy-
HTTPS_PROXYCorporate HTTPS proxy-
SSL_CERT_FILECustom CA certificate bundle-

Web Server Mode

Start the web server with custom host and port:

appsecone serve --config appsecone.json --host 0.0.0.0 --port 8080 --verbose

The server provides:

  • Server-side rendered dashboard at / (Jinja2 + HTMX, no JS build step)
  • RESTful JSON API under /api/ for programmatic access
  • Health probes at /health/live and /health/ready for container orchestration
  • SSE streaming for real-time sync progress at /api/admin/sync/stream

Tip: Use --verbose to enable detailed request logging with correlation IDs for debugging.


CLI Reference

AppSecOne ships a Typer-based CLI with five commands:

CommandDescriptionKey Options
appsecone serveStart the web dashboard server--config, --host, --port, --verbose
appsecone syncRun a one-time sync from Fortify SSC--config, --verbose
appsecone evaluateEvaluate release readiness (all or one repo)--config, --repo, --verbose
appsecone validateValidate a configuration file--config
appsecone versionShow AppSecOne version-

Examples

# Evaluate a single repository
appsecone evaluate --config appsecone.json --repo web-app
# Evaluate all repositories
appsecone evaluate --config appsecone.json --verbose
# Validate config before deployment
appsecone validate --config /etc/appsecone/production.json

API Reference

All JSON endpoints return {"ok": true, ...} on success and {"ok": false, "error": "..."} on failure.

Health & Status

MethodEndpointDescription
GET/health/liveLiveness probe - always returns 200
GET/health/readyReadiness probe - checks config, DB, sync freshness
GET/api/statusSystem status: version, uptime, config state, last sync

Overview & Trends

MethodEndpointDescription
GET/api/overviewPortfolio-wide severity breakdown and readiness summary
GET/api/trendsPortfolio trend data over a configurable period (?period=30)
GET/api/trends/{slug}Trend data for a single repository

Repositories

MethodEndpointDescription
GET/api/repositoriesPaginated list with filters: type, team, readiness, search, sort_by, sort_dir
GET/api/repositories/{slug}Detail view for a single repository
GET/api/repositories/{slug}/findingsFindings for a repository with severity, status, category filters

Findings

MethodEndpointDescription
GET/api/findingsAll findings, paginated, with filters: severity, status, repository, category, search

Readiness

MethodEndpointDescription
GET/api/readinessReadiness summary for all repositories
GET/api/readiness/{slug}Detailed readiness evaluation for one repository

Policies

MethodEndpointDescription
GET/api/policiesDefault policy and all named policy profiles

Waivers

MethodEndpointDescription
GET/api/waiversList all active waivers
POST/api/waiversCreate a waiver (requires repository_id, severity, reason, approved_by)
DELETE/api/waivers/{waiver_id}Revoke a waiver

Sync & Admin

MethodEndpointDescription
GET/api/sync-runsSync run history (?limit=20)
POST/api/admin/syncTrigger manual sync (background task)
POST/api/admin/sync/streamTrigger sync with SSE real-time progress stream
PUT/api/admin/sync-intervalUpdate sync interval (body: {"interval_minutes": 30})

Setup Wizard

MethodEndpointDescription
POST/api/setup/test-connectionTest connectivity to Fortify SSC
POST/api/setup/discoverDiscover projects and versions from Fortify SSC
POST/api/setup/save-configSave wizard configuration to appsecone.json

Export

MethodEndpointDescription
GET/api/export/findingsExport findings as CSV or JSON (?format=csv)
GET/api/export/dashboardExport current dashboard as standalone HTML

Internationalization

MethodEndpointDescription
GET/api/i18n/{locale}Translation catalog for the given locale

Server-Rendered Pages

MethodEndpointDescription
GET/Portfolio dashboard
GET/repo/{slug}Repository detail page
GET/findingsFindings explorer with filters
GET/policiesPolicy & waiver management page
GET/adminAdmin / system status page
GET/setupIntegration setup wizard

Note: State-changing endpoints (POST, PUT, DELETE, PATCH) require a valid API key when APPSECONE_API_KEY is set. See Security.


Architecture

AppSecOne follows a clean layered architecture - the domain layer has zero I/O dependencies, the application layer orchestrates async workflows, and the web layer is a thin adapter.

Project Structure

src/appsecone/
├── __init__.py # Version (0.1.0)
├── domain/ # Pure domain: enums, models, policy engine
├── config/ # JSON config loading + schema validation
├── fortify/ # Fortify SSC integration layer
│ ├── client/ # HTTP client, auth, endpoints
│ └── mappers/ # DTO → domain mapping
├── persistence/ # SQLite DAL (repos, findings, aggregates)
├── application/ # Service layer (sync, query)
├── analysis/ # Trend analytics & historical snapshots
├── presentation/ # Jinja2 renderer, view models, theme, templates
├── web/ # FastAPI server + middleware stack
├── cli/ # Typer CLI commands
├── i18n/ # Internationalization catalogs
└── shared/ # Logging, type aliases

Design Principles

  1. Domain purity - business rules live in domain/ with zero imports from infrastructure layers.
  2. Dependency inversion - application services depend on abstractions, not concrete implementations.
  3. Local read model - Fortify SSC is the source of truth, but all reads come from a local SQLite store for speed and resilience.
  4. Server-rendered first - Jinja2 templates with HTMX for interactivity; no SPA, no JS bundler.
  5. Configuration as code - all behavior is driven by a single JSON config file + environment variables.

Layer Dependency Flow

CLI / Web → Application → Domain
↓ ↑
Persistence Analysis
↓
Fortify (sync only)

Testing

AppSecOne has 464 tests covering domain logic, policy evaluation, API endpoints, persistence, Fortify integration, UX/UI regression, accessibility, and localization.

Run the test suite

# All tests
python3 -m pytest
# With coverage report
python3 -m pytest --cov=appsecone --cov-report=term-missing
# Unit tests only
python3 -m pytest tests/unit/

Test organization

DirectoryScopeWhat it covers
tests/unit/domain/UnitEnums, models, value objects
tests/unit/policy/UnitPolicy engine rule evaluation
tests/unit/mappers/UnitDTO → domain mapping (Fortify → domain)
tests/unit/presentation/UnitTemplate rendering, view models, UX/UI regression
tests/unit/shared/Uniti18n, networking, utilities
tests/unit/test_audit_regression.pyRegressionUX audit fixes - layout, a11y, responsive
tests/unit/test_blocker_regression.pyRegressionProduction blocker fixes - security, data integrity

Note: Async tests run automatically via pytest-asyncio with asyncio_mode = "auto". HTTP mocking uses respx.


Security

AppSecOne ships with a six-layer middleware stack applied to every request:

Middleware Stack (execution order)

#MiddlewarePurpose
1SecurityHeadersMiddlewareInjects X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, CSP, XSS protection
2RequestLoggingMiddlewareGenerates correlation IDs, logs method/path/status/duration for audit trails
3RateLimitMiddlewarePer-IP fixed-window: 120 req/min general, 5 req/min for /api/admin/* POST
4CORSMiddlewareConfigurable origins via APPSECONE_CORS_ORIGINS, restricts methods and headers
5CSRFMiddlewareOrigin/Referer validation on all state-changing requests (POST/PUT/DELETE/PATCH)
6APIKeyMiddlewareOptional HMAC-verified API key for admin endpoints via X-API-Key header

CSRF Protection

  • All state-changing methods require valid Origin or Referer matching the Host
  • Requests with X-API-Key bypass CSRF (machine-to-machine)
  • Requests without cookies bypass CSRF (no session to exploit)
  • API-style requests (Content-Type: application/json or X-Requested-With: XMLHttpRequest) are allowed
  • Health and streaming endpoints are exempt

API Key Authentication

  • Enabled when APPSECONE_API_KEY environment variable is set
  • Uses hmac.compare_digest() for timing-safe comparison (prevents timing attacks)
  • Protects all state-changing methods; GET requests are exempt
  • Returns 401 Unauthorized on invalid or missing key

Secret Handling

  • No hardcoded credentials - all secrets loaded from environment variables
  • Fortify token referenced by env var name in config (token_env_var), never stored in JSON
  • API key read from APPSECONE_API_KEY at startup
  • Token expiry validation for Fortify SSC authentication

Corporate Network (Zscaler / VPN / Proxy)

AppSecOne includes a centralized SSL context factory (shared/network.py) that automatically detects corporate CA certificates. Resolution order:

  1. SSL_CERT_FILE / REQUESTS_CA_BUNDLE env var (explicit override)
  2. certifi package (ships Mozilla CA bundle)
  3. macOS system keychain (automatic - includes corporate CAs like Zscaler)
  4. Python default

macOS / Linux - export your corporate CA bundle:

# macOS: extract certs from system keychain
security find-certificate -a -p \
/Library/Keychains/System.keychain \
/System/Library/Keychains/SystemRootCertificates.keychain \
>~/combined-ca-bundle.pem
# Add to shell profile (~/.zshrc or ~/.bashrc)export SSL_CERT_FILE=~/combined-ca-bundle.pem
export REQUESTS_CA_BUNDLE=~/combined-ca-bundle.pem

Proxy configuration:

export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080
export NO_PROXY=localhost,127.0.0.1,.internal.example.com

For detailed troubleshooting, see docs/troubleshooting.md.


Release Notes

See CHANGELOG.md for release history. AppSecOne follows Semantic Versioning.

Author

Created and maintained by POLPROG (@polprog-tech).


Contributing & Community

License

This project is licensed under the GNU Affero General Public License v3.0.

About

AppSecOne aggregates Fortify SSC vulnerability data, evaluates release readiness through deterministic security policies, and delivers real-time portfolio visibility with waivers, trends, and auditability.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages