MinIO API Reference¶
The MinIO API provides secure file storage for pentest artifacts, reports, and source code analysis.
Base URL¶
Internal service - accessed via n8n workflows.
Authentication¶
All requests require two headers:
| Header | Description |
|---|---|
X-API-Key |
User's API key (encrypted in database) |
X-Master-Key |
System master key from environment |
Bucket Naming¶
Bucket names must match one of these patterns:
| Pattern | Example | Use Case |
|---|---|---|
| UUID | abc123-def456-... |
Pentest artifacts |
team-UUID |
team-abc123-... |
Team shared storage |
Endpoints¶
Create Bucket¶
Creates a storage bucket for a pentest.
Authorization: User must own the pentest or retest.
Response:
Create Team Bucket¶
Creates a storage bucket for team collaboration.
Response:
Delete Bucket¶
Deletes a bucket and all its contents.
Response:
Upload ZIP File¶
Uploads a ZIP archive to a bucket.
Content-Type: multipart/form-data
Body: File field with .zip extension
Validation:
- Must be valid ZIP format
- Must have .zip extension
Response:
{
"status": "uploaded",
"filename": "source-code.zip",
"bucket": "abc123-def456",
"owner": "username"
}
Upload Any File¶
Uploads any file type to a bucket.
Content-Type: multipart/form-data
Body:
- file: The file to upload
- filename (optional): Override the filename
Response:
{
"status": "uploaded",
"filename": "report.pdf",
"bucket": "abc123-def456",
"content_type": "application/pdf",
"owner": "username"
}
Download File¶
Downloads a file from a bucket.
Response: File stream with appropriate Content-Type header.
Supported content types:
- application/zip
- application/pdf
- text/plain
- image/jpeg, image/png
List Files¶
Lists all files in a bucket.
Response:
{
"files": ["source.zip", "report.pdf", "findings.json"],
"bucket": "abc123-def456",
"owner": "username"
}
Delete File¶
Deletes a specific file from a bucket.
Response:
{
"status": "deleted",
"filename": "old-report.pdf",
"bucket": "abc123-def456",
"owner": "username"
}
Generate PDF from HTML¶
Converts an HTML report to PDF using WeasyPrint.
Workflow:
1. Downloads {bucket_name}.html from bucket
2. Converts to PDF using WeasyPrint
3. Uploads {bucket_name}.pdf to bucket
Timeout: 60 seconds
Response:
{
"status": "success",
"message": "PDF generated successfully",
"bucket": "abc123-def456",
"pdf_filename": "abc123-def456.pdf",
"owner": "username"
}
Convert PDF to Markdown¶
Converts a PDF to Markdown for LLM processing.
Workflow:
1. Downloads {bucket_name}-imported.pdf from bucket
2. Converts to Markdown using PyMuPDF4LLM (with OCR)
3. Uploads both PDF and Markdown to bucket
Response:
{
"status": "success",
"message": "PDF converted to markdown successfully",
"bucket": "abc123-def456",
"pdf_object": "abc123-def456-imported.pdf",
"markdown_object": "abc123-def456-imported.md",
"owner": "username"
}
Data Flow Diagrams¶
Upload Flow¶
sequenceDiagram
participant Client
participant MinIO API
participant MinIO Storage
participant PostgreSQL
Client->>MinIO API: POST /upload/{bucket}
MinIO API->>PostgreSQL: Verify bucket ownership
PostgreSQL-->>MinIO API: User authorized
MinIO API->>MinIO API: Validate ZIP format
MinIO API->>MinIO Storage: Store object
MinIO Storage-->>MinIO API: Object stored
MinIO API-->>Client: 200 OK + metadata
PDF Generation Flow¶
sequenceDiagram
participant n8n
participant MinIO API
participant MinIO Storage
participant WeasyPrint
n8n->>MinIO API: POST /generate-pdf/{bucket}
MinIO API->>MinIO Storage: Download HTML
MinIO Storage-->>MinIO API: HTML content
MinIO API->>WeasyPrint: Convert to PDF
WeasyPrint-->>MinIO API: PDF bytes
MinIO API->>MinIO Storage: Upload PDF
MinIO Storage-->>MinIO API: Stored
MinIO API-->>n8n: Success + filename
Security¶
Path Traversal Protection¶
The API blocks dangerous path patterns:
| Blocked Pattern | Reason |
|---|---|
.. |
Directory traversal |
./ |
Relative path |
// |
Path manipulation |
\ |
Windows path separator |
%2e, %2f, %5c |
URL-encoded variants |
%00 |
Null byte injection |
.filename |
Hidden files |
Authorization Flow¶
flowchart TD
A[Request] --> B{Master Key Valid?}
B -->|No| C[401 Unauthorized]
B -->|Yes| D{API Key Valid?}
D -->|No| C
D -->|Yes| E{User Owns Bucket?}
E -->|No| F[403 Forbidden]
E -->|Yes| G[Process Request]
Ownership is verified through: 1. Direct pentest ownership 2. Direct retest ownership 3. Team membership
Error Responses¶
| Status | Code | Description |
|---|---|---|
| 400 | invalid_bucket |
Bucket name doesn't match UUID pattern |
| 400 | invalid_filename |
Filename contains blocked patterns |
| 400 | invalid_zip |
File is not a valid ZIP archive |
| 401 | invalid_master_key |
Master key header missing/invalid |
| 401 | invalid_api_key |
API key not found in database |
| 403 | access_denied |
User doesn't own this bucket |
| 404 | bucket_not_found |
Bucket doesn't exist |
| 404 | file_not_found |
File doesn't exist in bucket |
| 500 | storage_error |
MinIO operation failed |
| 500 | conversion_timeout |
PDF generation exceeded 60s |
Example error response:
Configuration¶
Environment variables:
| Variable | Default | Description |
|---|---|---|
MINIO_ENDPOINT |
- | MinIO server address |
MINIO_ACCESS_KEY |
- | MinIO access key |
MINIO_SECRET_KEY |
- | MinIO secret key |
MINIO_BUCKET |
zipfiles |
Default bucket |
MINIO_SECURE |
false |
Use HTTPS |
MASTER_KEY |
- | API master key |
VAULT_MASTER_KEY |
- | Encryption key for API keys |