ApiPosture
A CLI security inspection tool for Python API frameworks. Performs static source-code analysis to identify authorization misconfigurations and security risks.
Terminal Output
Findings Report
Features
- Multi-Framework Support: FastAPI, Flask, Django REST Framework
- 8 Security Rules: Comprehensive detection of common authorization issues
- Multiple Output Formats: Terminal (Rich), JSON, Markdown
- Configurable: YAML-based configuration with suppressions
- CI/CD Ready: Exit codes based on severity for pipeline integration
Installation
pip install apiposture
Quick Start
# Scan current directory
apiposture scan .
# Scan specific path with JSON output
apiposture scan ./src --output json
# Scan and fail on high severity findings (for CI)
apiposture scan . --fail-on high
Security Rules
| Rule | Name | Severity | Description |
|---|---|---|---|
| AP001 | Public without explicit intent | High | Public endpoint without AllowAny or explicit marker |
| AP002 | Anonymous on write | High | AllowAny on POST/PUT/DELETE/PATCH |
| AP003 | Auth conflict | Medium | Method-level AllowAny overrides class auth |
| AP004 | Missing auth on writes | Critical | No auth on write endpoints |
| AP005 | Excessive roles | Low | >3 roles on single endpoint |
| AP006 | Weak role naming | Low | Generic names like "user", "admin" |
| AP007 | Sensitive keywords | Medium | admin/debug/export in public routes |
| AP008 | Endpoint without auth | High | No auth configuration at all |
Supported Frameworks
FastAPI
from fastapi import Depends, FastAPI
@app.get("/protected")
async def protected(user = Depends(get_current_user)):
...
Flask
from flask import Flask
from flask_login import login_required
@app.route("/protected")
@login_required
def protected():
...
Django REST Framework
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
class ProtectedView(APIView):
permission_classes = [IsAuthenticated]
Configuration
Create .apiposture.yaml in your project root:
rules:
disabled:
- AP006 # Disable weak role naming check
exclude:
- "**/tests/**"
- "**/migrations/**"
suppressions:
- rule: AP001
route: "/health"
reason: "Health check is intentionally public"
CLI Options
apiposture scan [PATH] [OPTIONS]
Options:
-o, --output Output format: terminal, json, markdown, html
-f, --output-file Write output to file
-c, --config Configuration file path
--severity Minimum severity: info, low, medium, high, critical
--fail-on Exit code 1 if findings at this severity
--sort-by Sort by: severity, route, method, classification
--classification Filter: public, authenticated, role_restricted
--method Filter: GET, POST, PUT, DELETE, PATCH
--route-contains Filter routes by substring
--framework Filter: fastapi, flask, django_drf
--rule Filter by rule ID
--no-color Disable colored output
--no-icons Disable icons
Development
# Clone the repository
git clone https://github.com/apiposture/apiposture-python
cd apiposture-python
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linter
ruff check src tests
# Run type checker
mypy src
License
MIT
Metadata
Release files for apiposture 1.0.20
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| apiposture-1.0.20.tar.gz | 38.3 kB | With provenance | Details for apiposture-1.0.20.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| apiposture-1.0.20-py3-none-any.whl | Python 3 | none | any | Details for apiposture-1.0.20-py3-none-any.whl |
Total release size: 98.6 kB
Release files / apiposture-1.0.20.tar.gz
| Download URL | apiposture-1.0.20.tar.gz |
|---|---|
| Size | 38.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f241e6ed98dd5942b0ec092364e013cd32aaa55710bea3832717a1d867ec05d1
|
|
BLAKE2b-256 checksum How to use checksums |
076936baced02185b4138dbe2a1455a1a372532135547ee799fbf0f5eefcb5b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 25, 2026.
Transparency logRelease files / apiposture-1.0.20-py3-none-any.whl
| Download URL | apiposture-1.0.20-py3-none-any.whl |
|---|---|
| Size | 60.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d1efdd1ad87ddca159e5f6b376569694fd5e002b0e3592f0e046a7c8e8360c5d
|
|
BLAKE2b-256 checksum How to use checksums |
2ada50e01e43b9a13d5a21664e94dfb0c1ad26073aca77a789a2dfa8d6627d47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 25, 2026.
Transparency logSecurity for apiposture 1.0.20
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for apiposture-1.0.20.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on May 25, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.