# AI Insights
Source: https://docs.casebender.com/en/alerts/ai-insights
Leverage AI-powered analysis for alert investigation
## Overview
The AI Insights tab provides automated analysis and recommendations powered by artificial intelligence. This feature helps analysts quickly understand alert context, identify patterns, and make informed decisions about alert handling.
## Analysis Categories
### Threat Assessment
* Risk scoring
* Severity recommendations
* Impact analysis
* Confidence rating
### Pattern Recognition
* Similar past alerts
* Known attack patterns
* Anomaly detection
* Behavioral analysis
### Context Enhancement
* Related external threats
* Industry context
* Historical perspective
* Environmental factors
## AI Capabilities
### Natural Language Processing
* Description analysis
* Context extraction
* Entity recognition
* Relationship mapping
### Machine Learning Models
* Pattern detection
* Anomaly identification
* Risk prediction
* Similarity scoring
### Automated Enrichment
* Threat intelligence correlation
* OSINT integration
* Historical data analysis
* Environmental context
## Insights Display
### Summary View
* Key findings
* Risk assessment
* Recommended actions
* Critical observations
### Detailed Analysis
* In-depth explanations
* Supporting evidence
* Confidence levels
* Alternative interpretations
### Recommendations
* Next steps
* Investigation paths
* Mitigation strategies
* Resource allocation
## Interactive Features
### Insight Exploration
1. Expand detailed analysis
2. View supporting evidence
3. Access related data
4. Track insight history
### Feedback Loop
* Mark insights helpful/unhelpful
* Add analyst notes
* Provide context
* Report inaccuracies
### Custom Analysis
* Request specific analysis
* Focus on particular aspects
* Adjust analysis parameters
* Save analysis preferences
## Best Practices
1. **Analysis Review**
* Validate AI findings
* Cross-reference data
* Document disagreements
* Track accuracy
2. **Investigation Flow**
* Start with summary
* Explore key findings
* Validate conclusions
* Document decisions
3. **Feedback Quality**
* Provide specific feedback
* Note false positives
* Suggest improvements
* Share context
## Model Training
### Data Sources
* Historical alerts
* Analyst feedback
* External threats
* Industry data
### Training Process
* Continuous learning
* Feedback incorporation
* Model updates
* Performance monitoring
## Next Steps
Configure automated responses
Explore alert analytics
# Alert Checklists
Source: https://docs.casebender.com/en/alerts/checklists
Configure governed response checklists and complete required alert steps.
Alert checklists give analysts a consistent, auditable set of response steps for every applicable alert. Administrators can target a checklist to every alert or to selected governed alert types such as phishing and malware. A checklist is copied from the effective published configuration when an alert is created or backfilled, so later changes do not silently rewrite an investigation.
## Complete an alert checklist
Open an alert and select the **Checklist** tab. Required and optional items are grouped separately. Each item shows its dependency, evidence requirement, policy source, revision, and completion or waiver history.
Select an item to open its detail panel. From there you can:
* review analyst guidance and state history;
* add Markdown comments, mentions, and attachments;
* provide required completion evidence;
* complete or reopen the item; and
* review the actor and time for completed or waived work.
Concurrent changes are protected by item revisions. If another analyst updates the same item first, refresh the checklist and review their change before trying again.
### Add an alert-specific step
When the effective policy allows alert-specific steps, select **Add step** from the checklist summary. Enter a title and optional guidance. The step is added to this alert only and is labeled **Alert-specific** so it cannot be confused with a governed policy requirement.
Alert-specific steps are optional by default. Checklist managers can mark a new step as required before closure. Policy-derived steps cannot be removed from an alert. Alert-specific steps can be archived, but their activity and audit history are retained.
## Close an alert
Use the close action and choose any status whose stage is **Closed**. The dialog shows required-item progress and links to remaining blockers.
* **Off** records progress without affecting closure.
* **Warn** identifies incomplete requirements but permits closure.
* **Block** prevents closure until every required item is completed or waived.
When policy permits a privileged override, an authorized user must provide a meaningful reason and acknowledge the remaining blockers. Overrides are retained in the audit trail.
## Configure policies
Administrators manage checklists in **Settings → Alert Checklists**. The page shows every checklist and whether it is on, off, or still needs setup.
To create one:
1. Select **New checklist** and give it a clear name.
2. Add the steps analysts should complete.
3. In **Settings**, choose whether it applies to **All alerts** or selected alert types.
4. Select **Save and enable**.
The checklist is then added to matching new alerts. Use the switch beside a checklist to turn it on or off. Turning it off preserves its steps and change history. The checklist library shows each checklist's target alert types, and the editor previews how many recently active alerts match.
Multiple enabled checklists can match the same alert. Their steps are merged by stable key using the existing global and organization precedence rules. The alert's Checklist tab explains which checklists were selected and why.
## Classify and reclassify alerts
The **Alert type** field uses a governed taxonomy that is separate from the integration source. For example, an alert can have source `crowdstrike` and type `malware`.
Changing an active alert's type immediately re-evaluates its checklist. Completed and waived work with the same stable key is preserved, new matching steps are added, and requirements that no longer apply are retired from the active list while remaining in audit history. Closed alerts preserve their historical checklist snapshot even if their classification is corrected.
Workflows can evaluate `alert.alertCategoryValue` and use the **Set Alert Type** action. Alert templates may also set `alertCategoryValue`; checklist resolution always runs after that classification is applied.
Use **Settings** to choose what happens when required steps are unfinished. **Change history** retains prior saved versions and rollback controls. Less common options, such as dependencies and stable automation keys, are grouped under **More options** for each step.
Super administrators manage checklists for all organizations and decide whether organization-specific checklists may supplement them. Organization administrators can only manage their current organization and cannot weaken locked global controls.
## Rollout and recovery
Backfill applies only to non-deleted alerts whose status stage is not **Closed**. Jobs are resumable and idempotent. Historical closed alerts are not changed.
Operators can temporarily set `ALERT_CHECKLIST_ENFORCEMENT_DISABLED=true` to stop checklist blocking without deleting checklist state or audit evidence.
# Alert Detail View
Source: https://docs.casebender.com/en/alerts/detail-view
Comprehensive view of individual alert information
## Overview
The Alert Detail View provides a comprehensive interface for viewing and managing individual alerts. It features a rich text editor for descriptions, file attachments, and multiple tabs for different aspects of the alert.
## Layout Structure
### Main Content Area
1. **Header Section**
* Back to list navigation
* Severity badge
* Editable title
* Action buttons
2. **Description Section**
* Rich text editor
* Support for formatting
* File attachment integration
* Image embedding
3. **Attachments Section**
* Image gallery with lightbox
* File list with previews
* Drag-and-drop upload
* Attachment management
### Right Sidebar
1. **Action Panel**
* Status updates
* Team assignments
* Tag management
* Custom field updates
* Case creation/linking
2. **Details Section**
* Creation information
* Last update timestamp
* Source details
* Reference information
### Activity Timeline
* Chronological activity log
* Status changes
* Assignment updates
* Comment additions
* Attachment uploads
## Tab Navigation
### Observables Tab
[Learn more about Observables](/en/alerts/observables)
* List of associated indicators
* Observable management
* Type categorization
* Enrichment status
### TTPs Tab
[Learn more about TTPs](/en/alerts/ttps)
* MITRE ATT\&CK mapping
* Technique details
* Procedure documentation
* Tactic categorization
### Similar Alerts Tab
[Learn more about Similar Alerts](/en/alerts/similar-alerts)
* Related alert discovery
* Similarity scoring
* Merge capabilities
* Pattern identification
### AI Insights Tab
[Learn more about AI Insights](/en/alerts/ai-insights)
* Automated analysis
* Risk assessment
* Recommended actions
* Pattern recognition
## Editing Capabilities
### Title Editing
* Direct inline editing
* Auto-save functionality
* Character limits
* Validation rules
### Description Management
* Rich text formatting
* Image embedding
* Link integration
* Version tracking
### File Attachments
* Multiple file upload
* Image preview
* File type support
* Size limitations
## Collaboration Features
### Comments and Notes
* Rich text comments
* @mentions support
* Reply threading
* Notification integration
### Team Assignment
* Single/multiple assignees
* Team visibility settings
* Assignment history
* Auto-assignment rules
## Best Practices
1. **Content Organization**
* Use clear titles
* Structure descriptions well
* Categorize attachments
* Tag appropriately
2. **Collaboration**
* Update status regularly
* Document key findings
* Use @mentions effectively
* Keep activity log clear
3. **Investigation**
* Review all tabs
* Document observations
* Link related items
* Update findings regularly
## Next Steps
Learn about observable management
Explore tactics and procedures
Understand alert correlation
Leverage AI analysis
# Alert List View
Source: https://docs.casebender.com/en/alerts/list-view
Navigate and manage multiple alerts efficiently
## Overview
The Alert List View provides a comprehensive interface for managing multiple alerts. It offers powerful filtering, bulk operations, and quick access to alert details.
## List Features
### Toolbar Actions
* **Multiple Selection**: Toggle checkbox to select multiple alerts
* **Refresh**: Update the alert list in real-time
* **Bulk Operations**:
* Create Case from selected alerts
* Merge alerts into existing case
* Bulk update alert properties
* Delete selected alerts
### Filtering and Search
* Search by alert title and description
* Filter by:
* Status
* Severity
* Assignee
* Reset filters to default view
### Selection Modes
1. **Individual Selection**
* Select alerts one by one
* Perform actions on specific alerts
2. **Bulk Selection**
* Select all visible alerts
* Select all matching alerts (across pages)
* Clear selection
## List Display
### Alert List Items
Each alert in the list shows:
* Severity indicator
* Title
* Status
* Assignment information
* Creation timestamp
* Quick action buttons
### Virtual Scrolling
* Efficient handling of large alert lists
* Load more functionality
* Smooth scrolling performance
## Bulk Operations
### Create Case
Convert multiple alerts into a new case:
1. Select relevant alerts
2. Click create case button
3. Fill case details
4. Confirm creation
### Merge with Case
Add alerts to an existing case:
1. Select alerts to merge
2. Click merge button
3. Search for target case
4. Confirm merge operation
### Bulk Update
Update multiple alerts simultaneously:
1. Select alerts to update
2. Click bulk update button
3. Choose fields to update
4. Apply changes
### Bulk Delete
Remove multiple alerts:
1. Select alerts to delete
2. Click delete button
3. Confirm deletion
## Empty States
### No Alerts
Displayed when no alerts exist:
* Informative message
* Guidance on creating alerts
### No Search Results
Shown when filters return no results:
* Suggestion to adjust filters
* Option to reset search
## Best Practices
1. **Selection Management**
* Use bulk selection for similar alerts
* Verify selection before bulk actions
* Clear selection after operations
2. **Filtering Strategy**
* Start with broad filters
* Refine based on results
* Use search for specific alerts
3. **Bulk Operations**
* Review selected items carefully
* Use preview when available
* Confirm irreversible actions
## Next Steps
Learn about detailed alert information
Master bulk alert management
# Alert Observables
Source: https://docs.casebender.com/en/alerts/observables
Manage indicators and observables associated with alerts
## Overview
The Observables tab allows you to track and manage various types of indicators associated with an alert. These observables can include IP addresses, domains, file hashes, and other relevant technical artifacts.
## Observable Types
### Network Indicators
* IP Addresses
* Domain Names
* URLs
* Email Addresses
* Network Services
### File Indicators
* File Hashes (MD5, SHA1, SHA256)
* File Names
* File Paths
* File Types
### System Indicators
* Registry Keys
* Process Names
* System Commands
* User Accounts
### Custom Indicators
* Custom Observable Types
* Organization-specific Indicators
* Industry-specific Artifacts
## Managing Observables
### Adding Observables
1. Click "Add Observable" button
2. Select observable type
3. Enter observable value
4. Add optional description
5. Set TLP/PAP levels if applicable
### Bulk Operations
* Import multiple observables
* Export observable list
* Bulk update TLP/PAP
* Bulk delete observables
### Observable Properties
* Type classification
* Value
* Description
* TLP (Traffic Light Protocol) level
* PAP (Permissible Actions Protocol) level
* First/Last seen timestamps
* Source information
## Observable Enrichment
### Automatic Enrichment
* Reputation data
* Geolocation information
* WHOIS data
* Historical context
* Related indicators
### Manual Analysis
* Add analysis notes
* Link to external sources
* Document investigation findings
* Tag related observables
## Visualization
### List View
* Sortable columns
* Quick filters
* Type indicators
* Enrichment status
### Relationship View
* Observable connections
* Related alerts
* Common patterns
* Timeline visualization
## Best Practices
1. **Data Quality**
* Validate observable format
* Remove false positives
* Document context
* Maintain consistent format
2. **Enrichment**
* Review enrichment data
* Update stale information
* Document findings
* Link related data
3. **Organization**
* Use consistent naming
* Group related observables
* Tag effectively
* Document relationships
## Next Steps
Explore tactics and procedures
Find related alerts
# Similar Alerts
Source: https://docs.casebender.com/en/alerts/similar-alerts
Discover and analyze related alerts
## Overview
The Similar Alerts tab helps identify and analyze alerts that may be related to the current alert. This feature uses various correlation methods to find potential connections and patterns across your alert data.
## Correlation Methods
### Content-based Similarity
* Title matching
* Description analysis
* Observable overlap
* TTP correlation
### Temporal Analysis
* Time-based clustering
* Frequency patterns
* Sequence detection
* Campaign timeline
### Contextual Correlation
* Source alignment
* Target comparison
* Attack pattern matching
* Team/Organization context
## Similarity Scoring
### Score Components
* Observable match percentage
* TTP overlap
* Temporal proximity
* Source correlation
* Target alignment
### Score Interpretation
* High confidence matches
* Potential relationships
* Weak correlations
* False positives
## Alert Management
### Viewing Similar Alerts
1. Sort by similarity score
2. Filter by time range
3. Group by correlation type
4. Focus on specific attributes
### Bulk Operations
* Select multiple alerts
* Create case from group
* Merge alerts
* Update status
### Alert Comparison
* Side-by-side view
* Difference highlighting
* Common attributes
* Unique characteristics
## Pattern Analysis
### Campaign Detection
* Alert clustering
* Pattern identification
* Campaign timeline
* Attack progression
### Threat Actor Analysis
* Common TTPs
* Observable patterns
* Target profiles
* Attack methodologies
## Visualization
### Timeline View
* Chronological display
* Frequency analysis
* Pattern highlighting
* Campaign mapping
### Relationship Graph
* Alert connections
* Observable links
* TTP relationships
* Pattern visualization
## Best Practices
1. **Analysis Workflow**
* Review highest scores first
* Validate relationships
* Document findings
* Update correlation rules
2. **Pattern Recognition**
* Look for campaigns
* Track progression
* Note anomalies
* Document insights
3. **Alert Management**
* Group related alerts
* Create cases appropriately
* Update statuses
* Document relationships
## Next Steps
Get AI-powered analysis
Configure correlation rules
# Alert TTPs
Source: https://docs.casebender.com/en/alerts/ttps
Track tactics, techniques, and procedures associated with alerts
## Overview
The TTPs (Tactics, Techniques, and Procedures) tab provides a comprehensive view of the MITRE ATT\&CK techniques and tactics associated with an alert, helping analysts understand and document adversary behavior.
## MITRE ATT\&CK Integration
### Framework Overview
* Enterprise ATT\&CK Matrix
* Mobile ATT\&CK Matrix
* ICS ATT\&CK Matrix
* Pre-ATT\&CK Tactics
### Mapping Capabilities
* Technique selection
* Sub-technique support
* Tactic categorization
* Confidence scoring
## Managing TTPs
### Adding Techniques
1. Browse or search ATT\&CK matrix
2. Select relevant technique
3. Choose sub-techniques if applicable
4. Set confidence level
5. Add supporting evidence
### Bulk Operations
* Import technique list
* Export TTP mapping
* Bulk update confidence
* Remove multiple techniques
### TTP Properties
* Technique ID
* Technique name
* Sub-technique details
* Confidence level
* Supporting evidence
* Detection status
* Mitigation status
## Documentation
### Evidence Collection
* Observable links
* Screenshot attachments
* Log excerpts
* Analysis notes
### Procedure Details
* Implementation specifics
* Tool usage
* Command syntax
* Execution timeline
## Analysis Features
### Pattern Recognition
* Common technique combinations
* Campaign correlation
* Actor attribution
* Similar incidents
### Impact Assessment
* Technique severity
* Asset scope
* Business impact
* Risk scoring
## Visualization
### Matrix View
* ATT\&CK matrix navigation
* Technique highlighting
* Sub-technique expansion
* Coverage mapping
### Timeline View
* Technique execution order
* Time-based correlation
* Pattern identification
* Campaign tracking
## Best Practices
1. **Technique Mapping**
* Verify technique matches
* Document evidence clearly
* Set appropriate confidence
* Link to observables
2. **Documentation**
* Detail procedure specifics
* Include context
* Reference sources
* Update findings
3. **Analysis**
* Look for patterns
* Compare with known actors
* Assess impact
* Plan mitigations
## Next Steps
Find related alerts
Get AI-powered analysis
# Alert Analytics
Source: https://docs.casebender.com/en/analytics/alert-analytics
Monitor and analyze security alerts with comprehensive metrics and visualizations.
## Overview
The Alert Analytics dashboard provides detailed insights into your security alerts:
!\[Alert Analytics Dashboard]
*Screenshot showing the main alert analytics dashboard*
## Key Metrics
### Total Alerts
* Total number of alerts
* Trend over time
* Percentage changes
* Alert volume patterns
!\[Total Alerts Card]
*Screenshot showing the total alerts metric card*
### Alert Status Distribution
View alerts by status:
* New alerts
* In Progress
* Imported
* Duplicated
* False Positive
* Ignored
!\[Alert Status Distribution]
*Screenshot showing the pie chart of alert status distribution*
### Alert Trend Analysis
Track alert patterns over time:
* Daily alert volumes
* Weekly trends
* Monthly comparisons
* Custom date ranges
!\[Alert Trend Chart]
*Screenshot showing the alert trend line chart*
### Severity Analysis
Monitor alerts by severity level:
* Critical alerts
* High severity
* Medium severity
* Low severity
Each severity level shows:
* Current count
* Historical trend
* Pattern analysis
* Impact assessment
!\[Severity Analysis]
*Screenshot showing the severity analysis charts*
### Top Alert Tags
View most common alert tags:
* Tag frequency
* Usage patterns
* Category distribution
* Trend analysis
!\[Top Tags Chart]
*Screenshot showing the top alert tags bar chart*
## Interactive Features
### Date Range Selection
Filter data by time period:
* Last 7 days
* Last 30 days
* Last 90 days
* Custom range
* Real-time updates
### Export Options
Export your analytics:
* PDF reports
* CSV data export
* Scheduled exports
* Custom formatting
### Visualization Controls
Customize your view:
* Chart types
* Data grouping
* Sorting options
* Filter controls
## Best Practices
### 1. Regular Monitoring
* Check daily volumes
* Track severity trends
* Monitor false positives
* Analyze patterns
### 2. Performance Analysis
* Response times
* Resolution rates
* Team efficiency
* Quality metrics
### 3. Trend Analysis
* Identify patterns
* Predict volumes
* Plan resources
* Optimize workflows
### 4. Report Generation
* Schedule reports
* Share insights
* Document findings
* Track progress
## Related Documentation
* [Case Analytics](./case-analytics.mdx)
* [Task Analytics](./task-analytics.mdx)
* [Analyst Performance](./analyst-performance.mdx)
# Analyst Performance
Source: https://docs.casebender.com/en/analytics/analyst-performance
Track and analyze individual and team performance metrics for security analysts.
## Overview
The Analyst Performance dashboard provides insights into individual and team performance:
!\[Analyst Performance Dashboard]
*Screenshot showing the main analyst performance dashboard*
## Key Metrics
### Cases Resolved
Track case resolution metrics:
* Total cases resolved
* Resolution rate
* Time to resolution
* Case complexity
!\[Cases Resolved Card]
*Screenshot showing the cases resolved metric card*
### Alerts Processed
Monitor alert handling:
* Total alerts processed
* Processing rate
* Alert types
* False positive rate
!\[Alerts Processed Card]
*Screenshot showing the alerts processed metric card*
### Average Response Time
Measure response efficiency:
* Initial response time
* Resolution time
* SLA compliance
* Time by priority
!\[Response Time Card]
*Screenshot showing the average response time metric card*
### Accuracy Rate
Track quality metrics:
* Decision accuracy
* False positive identification
* Quality assessment
* Improvement trends
!\[Accuracy Rate Card]
*Screenshot showing the accuracy rate metric card*
## Performance Analysis
### Individual Metrics
Track per-analyst performance:
* Workload distribution
* Specialization areas
* Efficiency metrics
* Quality indicators
### Team Metrics
Monitor team performance:
* Team capacity
* Collaboration patterns
* Knowledge sharing
* Resource utilization
## Best Practices
### 1. Performance Monitoring
* Regular reviews
* Goal tracking
* Skill development
* Process improvement
### 2. Quality Management
* Accuracy tracking
* Error analysis
* Training needs
* Best practices sharing
### 3. Resource Optimization
* Workload balancing
* Skill matching
* Capacity planning
* Team coordination
### 4. Continuous Improvement
* Performance feedback
* Training programs
* Process optimization
* Team development
## Related Documentation
* [Alert Analytics](./alert-analytics.mdx)
* [Case Analytics](./case-analytics.mdx)
* [Task Analytics](./task-analytics.mdx)
# Case Analytics
Source: https://docs.casebender.com/en/analytics/case-analytics
Track and analyze case management metrics with comprehensive visualizations and insights.
## Overview
The Case Analytics dashboard provides detailed insights into your case management:
!\[Case Analytics Dashboard]
*Screenshot showing the main case analytics dashboard*
## Key Metrics
### Total Cases
* Total number of cases
* Trend over time
* Percentage changes
* Case volume patterns
!\[Total Cases Card]
*Screenshot showing the total cases metric card*
### Case Status Distribution
View cases by status:
* New cases
* In Progress
* Under Review
* Resolved
* Closed
* Blocked
!\[Case Status Distribution]
*Screenshot showing the pie chart of case status distribution*
### Case Trend Analysis
Track case patterns over time:
* Daily case volumes
* Weekly trends
* Monthly comparisons
* Custom date ranges
!\[Case Trend Chart]
*Screenshot showing the case trend line chart*
### Severity Analysis
Monitor cases by severity level:
* Critical cases
* High severity
* Medium severity
* Low severity
Each severity level shows:
* Current count
* Historical trend
* Pattern analysis
* Impact assessment
!\[Severity Analysis]
*Screenshot showing the severity analysis charts*
### Top Case Tags
View most common case tags:
* Tag frequency
* Usage patterns
* Category distribution
* Trend analysis
!\[Top Tags Chart]
*Screenshot showing the top case tags bar chart*
## Interactive Features
### Date Range Selection
Filter data by time period:
* Last 7 days
* Last 30 days
* Last 90 days
* Custom range
* Real-time updates
### Export Options
Export your analytics:
* PDF reports
* CSV data export
* Scheduled exports
* Custom formatting
### Visualization Controls
Customize your view:
* Chart types
* Data grouping
* Sorting options
* Filter controls
## Best Practices
### 1. Regular Monitoring
* Check case volumes
* Track severity trends
* Monitor resolution times
* Analyze patterns
### 2. Performance Analysis
* Resolution rates
* Response times
* Team efficiency
* Quality metrics
### 3. Trend Analysis
* Identify patterns
* Predict volumes
* Plan resources
* Optimize workflows
### 4. Report Generation
* Schedule reports
* Share insights
* Document findings
* Track progress
## Related Documentation
* [Alert Analytics](./alert-analytics.mdx)
* [Task Analytics](./task-analytics.mdx)
* [Analyst Performance](./analyst-performance.mdx)
# Analytics
Source: https://docs.casebender.com/en/analytics/introduction
Comprehensive analytics and reporting features for monitoring alerts, cases, tasks, and analyst performance.
## Overview
The Analytics section provides detailed insights and metrics across different aspects of your security operations:
!\[Analytics Dashboard]
*Screenshot showing the main analytics dashboard with various metric cards*
## Available Dashboards
### 1. Alert Analytics
Monitor and analyze security alerts:
* Total alerts and trends
* Alert status distribution
* Severity breakdown
* Alert response times
* Top alert tags
!\[Alert Analytics]
*Screenshot showing the alert analytics dashboard*
### 2. Case Analytics
Track case management metrics:
* Case volume and trends
* Status distribution
* Severity levels
* Resolution times
* Case categories
!\[Case Analytics]
*Screenshot showing the case analytics dashboard*
### 3. Task Analytics
Monitor task performance:
* Task completion rates
* Priority distribution
* Time tracking
* Team workload
* Task dependencies
!\[Task Analytics]
*Screenshot showing the task analytics dashboard*
### 4. Analyst Performance
Track individual and team performance:
* Cases resolved
* Alerts processed
* Average response time
* Accuracy rate
* Team efficiency
!\[Analyst Performance]
*Screenshot showing the analyst performance dashboard*
## Common Features
### 1. Date Range Selection
Filter data by time period:
* Last 7 days
* Last 30 days
* Last 90 days
* Custom range
* Real-time updates
### 2. Export Options
Export your analytics:
* PDF reports
* Data download
* Scheduled reports
* Custom formats
### 3. Visualization Types
Analyze data through various charts:
* Line charts for trends
* Pie charts for distribution
* Bar charts for comparisons
* Heat maps for patterns
### 4. Interactive Elements
Interact with your data:
* Drill-down capabilities
* Filters and sorting
* Dynamic updates
* Custom views
## Best Practices
### 1. Regular Monitoring
* Check dashboards daily
* Track key metrics
* Identify trends
* Address anomalies
### 2. Performance Analysis
* Compare time periods
* Evaluate team metrics
* Monitor SLAs
* Track improvements
### 3. Report Generation
* Schedule regular reports
* Share key findings
* Document insights
* Track progress
### 4. Data-Driven Decisions
* Use metrics for planning
* Identify bottlenecks
* Optimize workflows
* Allocate resources
## Next Sections
* [Alert Analytics](./alert-analytics.mdx)
* [Case Analytics](./case-analytics.mdx)
* [Task Analytics](./task-analytics.mdx)
* [Analyst Performance](./analyst-performance.mdx)
# Task Analytics
Source: https://docs.casebender.com/en/analytics/task-analytics
Monitor and analyze task performance with comprehensive metrics and visualizations.
## Overview
The Task Analytics dashboard provides detailed insights into your task management:
!\[Task Analytics Dashboard]
*Screenshot showing the main task analytics dashboard*
## Key Metrics
### Total Tasks
* Total number of tasks
* Trend over time
* Percentage changes
* Task volume patterns
!\[Total Tasks Card]
*Screenshot showing the total tasks metric card*
### Task Status Distribution
View tasks by status:
* Open tasks
* In Progress
* Under Review
* Completed
* Blocked
* Cancelled
!\[Task Status Distribution]
*Screenshot showing the pie chart of task status distribution*
### Task Priority Analysis
Monitor tasks by priority level:
* High priority
* Medium priority
* Low priority
Each priority level shows:
* Current count
* Historical trend
* Completion rate
* Time tracking
!\[Priority Analysis]
*Screenshot showing the priority analysis charts*
### Completion Rate
Track task completion metrics:
* Daily completion rate
* Weekly trends
* Monthly averages
* Time to completion
!\[Completion Rate Chart]
*Screenshot showing the completion rate bar chart*
## Interactive Features
### Date Range Selection
Filter data by time period:
* Last 7 days
* Last 30 days
* Last 90 days
* Custom range
* Real-time updates
### Export Options
Export your analytics:
* PDF reports
* CSV data export
* Scheduled exports
* Custom formatting
### Visualization Controls
Customize your view:
* Chart types
* Data grouping
* Sorting options
* Filter controls
## Best Practices
### 1. Regular Monitoring
* Check task volumes
* Track priority trends
* Monitor completion rates
* Analyze patterns
### 2. Performance Analysis
* Completion times
* Response times
* Team efficiency
* Quality metrics
### 3. Trend Analysis
* Identify patterns
* Predict volumes
* Plan resources
* Optimize workflows
### 4. Report Generation
* Schedule reports
* Share insights
* Document findings
* Track progress
## Related Documentation
* [Alert Analytics](./alert-analytics.mdx)
* [Case Analytics](./case-analytics.mdx)
* [Analyst Performance](./analyst-performance.mdx)
# Activity Logs
Source: https://docs.casebender.com/en/audits/activity-logs
Track and analyze user activities and system events with comprehensive activity logging.
## Overview
Activity Logs provide a detailed record of all user actions and system events:
!\[Activity Logs View]
*Screenshot showing the activity logs interface*
## Activity Types
### User Activities
Track user interactions:
* Login/logout events
* Data modifications
* Status changes
* Document access
* Configuration updates
### System Events
Monitor system operations:
* Automated processes
* System updates
* Integration events
* Background tasks
* Error events
## Activity Components
### Activity Records
Each activity record includes:
* Timestamp
* User information
* Action type
* Affected resources
* Change details
### Event Context
Capture event details:
* Source information
* Target resources
* Action parameters
* Result status
* Related data
### Activity Metadata
Additional context:
* IP address
* Browser/device
* Session information
* Location data
* Access method
## Visualization
### Timeline View
Chronological display of activities:
* Time-based ordering
* Activity grouping
* Visual indicators
* Filter options
* Search capabilities
### Activity Analytics
Analyze activity patterns:
* Usage trends
* Common actions
* Peak periods
* User behavior
* System performance
## Interactive Features
### 1. Filtering
Filter activities by:
* Date range
* Activity type
* User
* Resource
* Status
### 2. Search
Search through activities:
* Full-text search
* Advanced filters
* Custom queries
* Saved searches
* Quick filters
### 3. Export
Export activity records:
* PDF reports
* CSV exports
* Custom formats
* Scheduled exports
* Data selection
## Best Practices
### 1. Activity Monitoring
* Regular review
* Pattern analysis
* Anomaly detection
* Performance tracking
* Security monitoring
### 2. Data Retention
* Retention policies
* Archival strategy
* Storage optimization
* Data cleanup
* Compliance requirements
### 3. Security Analysis
* Access patterns
* Security events
* Threat detection
* Compliance monitoring
* Audit preparation
## Related Documentation
* [Change History](./change-history.mdx)
* [Status Tracking](./status-tracking.mdx)
* [Compliance Monitoring](./compliance-monitoring.mdx)
# Change History
Source: https://docs.casebender.com/en/audits/change-history
Track and analyze changes to alerts, cases, and system configurations with detailed change history.
## Overview
The Change History feature provides a detailed record of all modifications:
!\[Change History View]
*Screenshot showing the change history interface*
## Change Types
### Alert Changes
Track modifications to alerts:
* Status changes
* Severity updates
* Assignee changes
* Description edits
* Title modifications
* TLP/PAP changes
* Team updates
* Tag modifications
* Organization changes
* Custom field updates
### Case Changes
Monitor case modifications:
* Status transitions
* Assignment changes
* Priority updates
* Description edits
* Team changes
* Tag updates
* Custom field modifications
### System Changes
Track system-level changes:
* Configuration updates
* Integration changes
* Workflow modifications
* Permission updates
* Role assignments
## Change Details
### Change Records
Each change record includes:
* Change type
* Previous value
* New value
* Timestamp
* User information
* Change comments
### User Information
Track who made changes:
* User name
* Profile picture
* Email address
* Role information
* Team association
### Change Comments
Document change context:
* Change reasons
* Additional notes
* Related references
* Decision context
* Follow-up actions
## Visualization
### Timeline View
Chronological display of changes:
* Time-based ordering
* Visual indicators
* Change grouping
* Filter options
* Search capabilities
### Change Comparison
Compare changes visually:
* Side-by-side view
* Highlight differences
* Track modifications
* Show relationships
* Identify patterns
## Interactive Features
### 1. Filtering
Filter change history by:
* Date range
* Change type
* User
* Entity type
* Field changes
### 2. Search
Search through changes:
* Full-text search
* Advanced filters
* Custom queries
* Saved searches
* Quick filters
### 3. Export
Export change records:
* PDF reports
* CSV exports
* Custom formats
* Scheduled exports
* Data selection
## Best Practices
### 1. Change Documentation
* Add clear comments
* Provide context
* Link related changes
* Document decisions
* Include references
### 2. Change Review
* Regular audits
* Pattern analysis
* Anomaly detection
* Compliance checks
* Quality assurance
### 3. Change Management
* Follow procedures
* Document approvals
* Track dependencies
* Monitor impact
* Update documentation
## Related Documentation
* [Status Tracking](./status-tracking.mdx)
* [Activity Logs](./activity-logs.mdx)
* [Compliance Monitoring](./compliance-monitoring.mdx)
# Compliance Monitoring
Source: https://docs.casebender.com/en/audits/compliance-monitoring
Monitor and ensure compliance with regulatory requirements and internal policies through comprehensive auditing.
## Overview
Compliance Monitoring provides tools and features to track, analyze, and maintain regulatory compliance:
!\[Compliance Monitoring View]
*Screenshot showing the compliance monitoring interface*
## Compliance Features
### Policy Tracking
Monitor policy adherence:
* Policy requirements
* Compliance status
* Policy updates
* Exception tracking
* Violation alerts
### Regulatory Compliance
Track regulatory requirements:
* Regulatory frameworks
* Compliance standards
* Audit requirements
* Documentation needs
* Reporting obligations
## Monitoring Components
### Compliance Records
Each compliance record includes:
* Requirement details
* Status information
* Due dates
* Responsible parties
* Documentation links
### Assessment Data
Track compliance assessments:
* Evaluation criteria
* Assessment results
* Gap analysis
* Remediation plans
* Follow-up actions
### Documentation
Maintain compliance documents:
* Policy documents
* Procedures
* Evidence files
* Audit reports
* Certifications
## Visualization
### Dashboard View
Comprehensive compliance overview:
* Status indicators
* Risk levels
* Due dates
* Progress tracking
* Alert notifications
### Compliance Analytics
Analyze compliance data:
* Compliance rates
* Trend analysis
* Risk assessment
* Performance metrics
* Gap identification
## Interactive Features
### 1. Filtering
Filter compliance data by:
* Requirement type
* Status
* Due date
* Risk level
* Department
### 2. Search
Search compliance records:
* Full-text search
* Advanced filters
* Custom queries
* Saved searches
* Quick filters
### 3. Reporting
Generate compliance reports:
* Status reports
* Audit reports
* Gap analysis
* Risk assessments
* Executive summaries
## Best Practices
### 1. Regular Monitoring
* Scheduled reviews
* Status updates
* Risk assessments
* Gap analysis
* Action tracking
### 2. Documentation Management
* Version control
* Evidence collection
* Document organization
* Access control
* Retention policies
### 3. Risk Management
* Risk assessment
* Control testing
* Issue tracking
* Remediation planning
* Progress monitoring
## Related Documentation
* [Change History](./change-history.mdx)
* [Status Tracking](./status-tracking.mdx)
* [Activity Logs](./activity-logs.mdx)
# Audit Logs
Source: https://docs.casebender.com/en/audits/introduction
Track and monitor changes across alerts, cases, and system activities with comprehensive audit logging.
## Overview
The Audit Logs system provides detailed tracking of changes and activities across the platform:
!\[Audit Logs Dashboard]
*Screenshot showing the main audit logs interface*
## Key Features
### 1. Change Tracking
Monitor changes to:
* Alert status and severity
* Case assignments and updates
* Team modifications
* Organization changes
* Custom field updates
### 2. Status History
Track status transitions:
* Status changes
* Time in each status
* Change comments
* User attribution
* Timestamp tracking
### 3. Activity Logging
Record user activities:
* User actions
* System events
* Authentication events
* API access logs
* Integration activities
### 4. Compliance Tracking
Monitor compliance-related metrics:
* Resolution quality
* Compliance scores
* Risk assessments
* Time to resolution
* Trend analysis
## Audit Components
### Change History
Each audit entry includes:
* Previous and new values
* Change timestamp
* User information
* Change comments
* Related entities
### Status Tracking
Monitor status workflows:
* Status transitions
* Duration in status
* Status comments
* Workflow patterns
* Resolution paths
### User Attribution
Track user activities:
* Action performer
* Affected users
* Team changes
* Permission updates
* Role modifications
## Interactive Features
### 1. Filtering
Filter audit logs by:
* Date range
* User
* Action type
* Entity type
* Status changes
### 2. Export Options
Export audit data:
* PDF reports
* CSV exports
* Scheduled reports
* Custom formats
### 3. Search Capabilities
Search through logs:
* Full-text search
* Advanced filters
* Custom queries
* Saved searches
## Best Practices
### 1. Regular Review
* Monitor changes daily
* Review critical changes
* Track unusual patterns
* Investigate anomalies
### 2. Compliance Management
* Track required changes
* Monitor compliance
* Document reviews
* Maintain records
### 3. Security Monitoring
* Review access patterns
* Track authentication
* Monitor API usage
* Investigate alerts
### 4. Documentation
* Document changes
* Maintain history
* Track decisions
* Record comments
## Next Sections
* [Change History](./change-history.mdx)
* [Status Tracking](./status-tracking.mdx)
* [Activity Logs](./activity-logs.mdx)
* [Compliance Monitoring](./compliance-monitoring.mdx)
# Status Tracking
Source: https://docs.casebender.com/en/audits/status-tracking
Monitor and analyze status changes and transitions with comprehensive status history tracking.
## Overview
The Status Tracking feature provides detailed insights into status changes and time spent in each status:
!\[Status Tracking View]
*Screenshot showing the status tracking interface*
## Status History
### Status Changes
Track status transitions:
* Previous status
* New status
* Change timestamp
* User information
* Change comments
### Time Tracking
Monitor time in each status:
* Duration calculation
* Status breakdowns
* Time analytics
* Trend analysis
* SLA monitoring
## Status Components
### Status Records
Each status record includes:
* Status values
* Transition time
* Duration
* User attribution
* Comments
### User Information
Track who made status changes:
* User name
* Profile picture
* Role information
* Team association
* Change context
### Status Comments
Document status changes:
* Change reasons
* Additional notes
* Related issues
* Decision context
* Follow-up actions
## Visualization
### Timeline View
Chronological display of status:
* Time-based ordering
* Visual indicators
* Status grouping
* Filter options
* Search capabilities
### Status Analytics
Analyze status patterns:
* Time distribution
* Common transitions
* Bottleneck detection
* Efficiency metrics
* Trend analysis
## Interactive Features
### 1. Filtering
Filter status history by:
* Date range
* Status type
* User
* Duration
* Comments
### 2. Search
Search through status changes:
* Full-text search
* Advanced filters
* Custom queries
* Saved searches
* Quick filters
### 3. Export
Export status records:
* PDF reports
* CSV exports
* Custom formats
* Scheduled exports
* Data selection
## Best Practices
### 1. Status Documentation
* Add clear comments
* Provide context
* Document decisions
* Track dependencies
* Include references
### 2. Status Review
* Regular audits
* Pattern analysis
* Bottleneck detection
* Efficiency checks
* Process improvement
### 3. Time Management
* Monitor durations
* Track SLAs
* Identify delays
* Optimize workflows
* Improve efficiency
## Related Documentation
* [Change History](./change-history.mdx)
* [Activity Logs](./activity-logs.mdx)
* [Compliance Monitoring](./compliance-monitoring.mdx)
# AI Features in Case Management
Source: https://docs.casebender.com/en/cases/ai-features
This guide covers the AI-powered features available in the case management system, designed to enhance investigation efficiency and decision-making.
## Overview
AI features provide automated analysis, insights, and recommendations to help analysts work more effectively:
!\[AI Features Overview]
*Screenshot showing the AI features dashboard*
## AI Insights Tab
### Automated Analysis
The AI Insights tab provides:
1. **Case Summary**:
* Key findings
* Risk assessment
* Recommended actions
* Similar cases
2. **Pattern Detection**:
* Behavioral patterns
* Attack techniques
* Anomaly detection
* Trend analysis
!\[AI Insights Interface]
*Screenshot of the AI Insights tab showing analysis results*
## Key Features
### 1. Similar Case Detection
Automatically identifies related cases:
* Pattern matching
* Behavioral similarity
* Shared indicators
* Historical correlation
### 2. Threat Analysis
AI-powered threat assessment:
* Risk scoring
* Impact analysis
* Threat actor attribution
* Attack pattern matching
### 3. Recommendation Engine
Provides actionable recommendations:
* Next steps
* Investigation paths
* Mitigation strategies
* Resource allocation
### 4. Natural Language Processing
Advanced text analysis:
* Content summarization
* Entity extraction
* Relationship mapping
* Sentiment analysis
## Using AI Features
### Accessing AI Insights
1. Open a case
2. Navigate to AI Insights tab
3. View automated analysis
4. Explore recommendations
### Interpreting Results
Understanding AI outputs:
* Confidence scores
* Supporting evidence
* Related findings
* Action priorities
!\[AI Results Interpretation]
*Screenshot showing how to interpret AI analysis results*
## Configuration Options
### AI Feature Settings
Configure AI behavior:
* Analysis frequency
* Confidence thresholds
* Data sources
* Integration points
### Model Selection
Choose AI models for:
* Pattern recognition
* Text analysis
* Risk assessment
* Recommendation generation
!\[AI Configuration]
*Screenshot of AI feature configuration options*
## Integration Features
### External AI Services
Integration with:
* OpenAI services
* Custom ML models
* Third-party AI tools
* Threat intelligence platforms
### Data Sources
AI analysis uses:
* Case history
* Alert data
* Threat intelligence
* External feeds
## Best Practices
### 1. Data Quality
Ensure quality inputs:
* Complete case documentation
* Accurate metadata
* Relevant observables
* Clear descriptions
### 2. AI Assistance
Effective use of AI:
* Verify AI findings
* Combine with human analysis
* Document AI insights
* Provide feedback
### 3. Continuous Learning
Improve AI performance:
* Regular model updates
* Feedback integration
* Performance monitoring
* Training data updates
## Privacy and Security
### Data Protection
AI feature security:
* Data encryption
* Access controls
* Audit logging
* Privacy compliance
### Ethical Considerations
Responsible AI use:
* Bias prevention
* Decision transparency
* Human oversight
* Ethical guidelines
!\[Privacy Settings]
*Screenshot showing AI privacy and security settings*
## Performance Metrics
### AI Effectiveness
Track AI performance:
* Accuracy rates
* Time savings
* False positive rates
* User adoption
### Impact Analysis
Measure business impact:
* Resolution time
* Decision quality
* Resource efficiency
* Cost savings
## Troubleshooting
### Common Issues
Address AI-related problems:
1. **Analysis Delays**:
* Check data sources
* Verify API access
* Monitor system resources
2. **Accuracy Issues**:
* Review training data
* Adjust thresholds
* Update models
* Gather feedback
!\[Troubleshooting Guide]
*Screenshot showing AI troubleshooting interface*
## Future Developments
Upcoming AI features:
* Advanced analytics
* Predictive modeling
* Automated reporting
* Enhanced visualization
For more information about working with cases, see [Working with Cases](./working-with-cases.mdx).
# Creating Cases
Source: https://docs.casebender.com/en/cases/creating-cases
This guide explains the different ways to create cases in the system and the available options during case creation.
## Methods of Creation
### 1. Manual Creation
Cases can be created manually through the user interface in several ways:
* Using the "New Case" button in the cases list view
* From the quick actions menu in the navigation bar
* Through the case templates in the settings
!\[Create Case Dialog]
*Screenshot showing the case creation dialog with all available fields*
### 2. From Templates
Case templates provide a standardized way to create cases with predefined fields:
* Choose from available templates or start with a blank case
* Templates can include pre-filled fields and default values
* Organization-specific templates are supported
!\[Case Templates]
*Screenshot showing the template selection dialog during case creation*
### 3. From Alerts
Cases can be automatically or manually created from security alerts:
* Convert single alerts to cases
* Merge multiple alerts into a single case
* Inherit alert properties (severity, TLP, etc.)
## Required Fields
When creating a case, the following fields are mandatory:
* **Title**: A clear, descriptive name for the case
* **Status**: Initial status (defaults to "New")
* **Severity**: Impact level (1-5)
* **TLP**: Traffic Light Protocol classification
* **PAP**: Permissible Actions Protocol level
## Optional Fields
Additional fields that can be specified during creation:
* **Description**: Detailed information about the case
* **Tags**: Custom labels for categorization
* **Assignee**: Team member responsible for the case
* **Custom Fields**: Organization-specific data fields
* **Organizations**: Visibility settings for organizations
## Case Creation Settings
Administrators can configure various aspects of case creation:
* Default values for new cases
* Required and optional fields
* Available templates
* Automation rules for case creation
* Organization-specific settings
!\[Case Settings]
*Screenshot showing the administrative settings for case creation*
## Best Practices
1. **Titles**: Use clear, descriptive titles that include key information
2. **Templates**: Create templates for common case types to ensure consistency
3. **Severity**: Follow organization guidelines for severity assignment
4. **TLP/PAP**: Carefully consider information sharing restrictions
5. **Custom Fields**: Use custom fields to capture organization-specific data
## Automation Options
Cases can be created automatically through various triggers:
* Alert-based triggers
* Integration webhooks
* API endpoints
* Scheduled workflows
## Next Steps
After creating a case:
1. Add relevant observables and artifacts
2. Create initial tasks
3. Link related alerts
4. Assign team members
5. Add detailed documentation
For more information on working with cases after creation, see [Working with Cases](./working-with-cases.mdx).
# Case Management
Source: https://docs.casebender.com/en/cases/introduction
The Case Management system is a comprehensive solution for tracking, managing, and resolving security incidents and investigations. This documentation covers all aspects of the case management functionality.
## Overview
Cases are the core entities for managing security incidents, investigations, and related activities. Each case represents a distinct security event or investigation that needs to be tracked and resolved.
!\[Case List View]
*Screenshot showing the main case list view with filters, search, and case cards*
## Key Features
* **Case Lifecycle Management**: Track cases from creation to resolution
* **Customizable Status Workflows**: Configure case statuses to match your organization's processes
* **Team Collaboration**: Assign cases to team members and track their progress
* **Rich Metadata**: Track severity, TLP (Traffic Light Protocol), and PAP (Permissible Actions Protocol)
* **Tagging System**: Organize cases with customizable tags
* **Integration with Alerts**: Link related alerts to cases
* **AI Insights**: Automated analysis and insights for cases (when enabled)
* **Audit Trail**: Complete timeline of case activities and changes
## Case Properties
### Core Properties
* **Case ID**: Unique identifier (auto-generated)
* **Title**: Descriptive name of the case
* **Description**: Detailed information about the case
* **Status**: Current state in the workflow (New, InProgress, Closed)
* **Severity**: Impact level (1-5)
* **TLP**: Traffic Light Protocol classification
* **PAP**: Permissible Actions Protocol level
* **Tags**: Custom labels for categorization
* **Custom Fields**: Organization-specific additional data
### Metadata
* **Created By**: User who created the case
* **Created At**: Timestamp of case creation
* **Updated At**: Last modification timestamp
* **Assigned To**: Team member responsible for the case
* **Organizations**: Associated organizations (for multi-tenant setups)
## Related Components
Cases are connected to several other components:
* **Alerts**: Security alerts that triggered or are related to the case
* **Observables**: Artifacts and indicators associated with the case
* **Tasks**: Action items and to-dos within the case
* **TTPs**: Tactics, Techniques, and Procedures identified in the case
* **Timeline**: Chronological record of case activities
* **AI Insights**: AI-powered analysis and recommendations (if enabled)
!\[Case Detail View]
*Screenshot showing the detailed view of a case with all its components and tabs*
## Next Sections
* [Creating Cases](./creating-cases.mdx)
* [Case Workflows](./workflows.mdx)
* [Working with Cases](./working-with-cases.mdx)
* [Case Settings](./settings.mdx)
* [AI Features](./ai-features.mdx)
# Case Settings
Source: https://docs.casebender.com/en/cases/settings
This guide covers the configuration options and settings available for customizing the case management system.
## Access Settings
Navigate to Settings > Cases to configure case-related options:
!\[Case Settings Page]
*Screenshot showing the main case settings interface*
## Status Configuration
### Managing Case Statuses
Configure the available case statuses:
1. **Create Status**:
* Label and description
* Color coding
* Stage assignment
* Unique value
2. **Edit Status**:
* Modify existing status properties
* Update color and label
* Change stage assignment
3. **Delete Status**:
* Remove unused statuses
* Handle cases with deleted status
!\[Status Management]
*Screenshot of the status management interface*
## Templates
### Case Templates
Create and manage case templates:
* Define default values
* Set required fields
* Create specialized templates
* Organization-specific templates
### Template Properties
Configure for each template:
* Name and description
* Default field values
* Required fields
* Automation rules
* Team assignments
!\[Template Configuration]
*Screenshot showing template creation and editing*
## Field Configuration
### Custom Fields
Add organization-specific fields:
* Field types (text, number, date, etc.)
* Required/optional settings
* Default values
* Field validation
### Field Display
Configure how fields appear:
* Field order
* Grouping
* Visibility conditions
* Mobile display
!\[Custom Fields]
*Screenshot of custom field configuration*
## Automation Settings
### Workflow Rules
Configure automated actions:
1. **Triggers**:
* Case creation
* Status changes
* Field updates
* Time-based events
2. **Actions**:
* Status updates
* Assignments
* Notifications
* Integration calls
!\[Workflow Automation]
*Screenshot of workflow automation settings*
## Team Settings
### Access Control
Configure team-based settings:
* Role permissions
* Team assignments
* Visibility rules
* Collaboration settings
### Assignment Rules
Set up case assignment rules:
* Auto-assignment
* Load balancing
* Skill-based routing
* Backup assignments
!\[Team Configuration]
*Screenshot showing team and assignment settings*
## Integration Settings
### External Systems
Configure integrations with:
* SIEM platforms
* Ticketing systems
* Communication tools
* Custom applications
### API Configuration
Manage API settings:
* API keys
* Webhook endpoints
* Rate limits
* Authentication
!\[Integration Settings]
*Screenshot of integration configuration*
## Notification Settings
### Email Notifications
Configure email alerts for:
* Case creation
* Status changes
* Assignments
* Comments
* Due dates
### Other Notifications
Set up notifications for:
* Slack/Teams
* Mobile push
* Custom webhooks
* System alerts
!\[Notification Configuration]
*Screenshot showing notification settings*
## Analytics Settings
### Metrics Configuration
Configure tracking for:
* Response times
* Resolution rates
* Team performance
* Custom metrics
### Reporting
Set up report templates:
* Case summaries
* Team reports
* Custom reports
* Scheduled reports
!\[Analytics Settings]
*Screenshot of analytics and reporting configuration*
## Best Practices
1. **Status Management**:
* Keep status list concise
* Use clear color coding
* Document status meanings
2. **Templates**:
* Create templates for common cases
* Review and update regularly
* Get team feedback
3. **Fields**:
* Only add necessary fields
* Use clear field labels
* Group related fields
4. **Automation**:
* Start with simple rules
* Test thoroughly
* Monitor performance
5. **Permissions**:
* Follow least privilege
* Regular access review
* Document role requirements
For information about working with cases, see [Working with Cases](./working-with-cases.mdx).
# Case Workflows
Source: https://docs.casebender.com/en/cases/workflows
Case workflows define how cases progress through your organization's incident response or investigation process. This guide explains how to work with and customize case workflows.
## Case Status Stages
Cases can be in one of three main stages:
1. **New**: Recently created cases requiring initial triage
2. **InProgress**: Cases actively being worked on
3. **Closed**: Resolved or completed cases
!\[Case Status Flow]
*Diagram showing the progression of cases through different status stages*
## Customizable Status Labels
Within each stage, organizations can create custom status labels:
* **New Stage**: Initial Triage, Pending Review, etc.
* **InProgress Stage**: Investigating, Waiting for Response, etc.
* **Closed Stage**: Resolved, False Positive, etc.
### Status Properties
Each status has the following properties:
* **Label**: Display name for the status
* **Color**: Visual indicator for the status
* **Stage**: Associated workflow stage
* **Can Delete**: Whether the status can be removed
* **Value**: Unique identifier for the status
!\[Status Management]
*Screenshot of the status management interface in settings*
## Workflow Automation
### Triggers
Workflows can be automated based on various triggers:
* **CaseCreated**: When a new case is created
* **CaseUpdated**: When case properties are modified
* **CaseDeleted**: When a case is removed
### Actions
Automated actions can include:
* Status changes
* Assignment updates
* Notification generation
* Integration with external systems
* Custom script execution
## Status Transitions
### Manual Transitions
Users can manually change case status based on their permissions:
* From the case detail view
* Through bulk actions in the case list
* Via the API
### Automated Transitions
Status can change automatically based on:
* Time-based rules
* Alert updates
* External system triggers
* Workflow automation rules
## Permissions and Roles
Status management is controlled by user permissions:
* **caseUpdate**: Required to change case status
* **caseCreate**: Needed to set initial status
* **caseDelete**: Required for certain status transitions
## Workflow Analytics
Track and analyze your case workflows:
* Time in each status
* Common transition patterns
* Bottlenecks and delays
* Team performance metrics
!\[Workflow Analytics]
*Screenshot showing workflow analytics dashboard*
## Best Practices
1. **Status Clarity**: Use clear, descriptive status names
2. **Color Coding**: Choose distinct colors for different stages
3. **Automation**: Automate routine status changes
4. **Metrics**: Monitor time spent in each status
5. **Documentation**: Maintain clear status transition guidelines
## Configuration
### Adding New Status
1. Navigate to Case Status settings
2. Click "Add Status"
3. Configure properties:
* Label
* Stage
* Color
* Value
4. Save changes
### Modifying Workflows
1. Access Workflow settings
2. Create or edit workflow rules
3. Define triggers and actions
4. Test workflow automation
5. Deploy changes
## Integration
Workflow status can integrate with:
* External ticketing systems
* SIEM platforms
* Communication tools
* Custom applications
For more information on working with cases, see [Working with Cases](./working-with-cases.mdx).
# Working with Cases
Source: https://docs.casebender.com/en/cases/working-with-cases
This guide covers the day-to-day operations and features available when working with cases in the system.
## Case Detail View
The case detail view is your primary workspace for managing cases:
!\[Case Detail Interface]
*Screenshot showing the main case detail interface with all components*
### Key Areas
1. **Header**: Case title, ID, and quick actions
2. **Details Panel**: Core case properties and metadata
3. **Tabs**: Access different case components
4. **Activity Timeline**: Recent updates and changes
## Case Components
### 1. Tasks
Tasks help track action items within a case:
* Create and assign tasks
* Set priorities and due dates
* Track task completion
* Add task notes and attachments
!\[Tasks Tab]
*Screenshot of the tasks management interface*
### 2. Observables
Manage artifacts and indicators:
* Add files, IPs, domains, and other observables
* Automatic enrichment
* Relationship visualization
* Threat intelligence lookup
!\[Observables Tab]
*Screenshot showing observable management and analysis*
### 3. TTPs (Tactics, Techniques, and Procedures)
Map case activities to known attack patterns:
* MITRE ATT\&CK® framework integration
* Custom TTP definitions
* Visual attack flow mapping
* Related procedure documentation
!\[TTPs Tab]
*Screenshot of the TTP mapping interface*
### 4. Timeline
Chronological view of case activities:
* Automatic event tracking
* Manual timeline entries
* Filter and search capabilities
* Evidence timeline reconstruction
!\[Timeline Tab]
*Screenshot showing the case timeline view*
### 5. AI Insights
AI-powered analysis and recommendations:
* Automated case analysis
* Similar case detection
* Recommendation engine
* Pattern recognition
!\[AI Insights Tab]
*Screenshot of AI-powered insights and recommendations*
## Case Actions
### Assignment and Collaboration
* Assign cases to team members
* Transfer ownership
* Add collaborators
* Team notifications
### Linking and Relationships
* Link related cases
* Connect alerts
* Establish observable relationships
* Create case groups
### Documentation
* Add notes and comments
* Attach files and evidence
* Generate reports
* Export case data
### Case Merging
When multiple cases are related:
1. Select cases to merge
2. Choose primary case
3. Review relationships
4. Confirm merge action
## Analysis Tools
### 1. Search and Filters
* Full-text search
* Advanced filtering
* Saved searches
* Custom views
### 2. Visualizations
* Relationship graphs
* Timeline views
* Statistical analysis
* Custom dashboards
### 3. Reporting
* Case summaries
* Status reports
* Team metrics
* Custom report templates
## Best Practices
1. **Documentation**: Keep detailed notes and updates
2. **Observables**: Add context to all observables
3. **Tasks**: Break down complex investigations
4. **Timeline**: Document key findings and decisions
5. **Collaboration**: Use comments for team communication
## Keyboard Shortcuts
Common actions have keyboard shortcuts:
* `Ctrl/Cmd + S`: Save changes
* `Ctrl/Cmd + E`: Edit mode
* `Ctrl/Cmd + F`: Search
* `Esc`: Cancel/Close
## Mobile Access
The case interface is responsive and supports:
* Mobile viewing
* Basic editing
* Task management
* Status updates
!\[Mobile Interface]
*Screenshot showing the mobile case interface*
## Integration Features
Cases integrate with:
* Email notifications
* Slack/Teams messages
* Webhook triggers
* External systems
For information about case workflows and status management, see [Case Workflows](./workflows.mdx).
# Deploy to AWS
Source: https://docs.casebender.com/en/deployment/aws
Deploy CaseBender on Amazon Web Services (AWS)
Reference architecture only. This page is not a production-certified deployment
procedure and predates the current activation, image-pinning, secret-management,
and network-isolation baseline. Use the [supported on-premises guide](/en/quickstart)
or complete an enterprise architecture review before deployment.
## Overview
This guide walks you through deploying CaseBender on AWS using pre-built Docker images with Amazon ECS (Elastic Container Service) and Fargate.
## Prerequisites
1. [AWS Account](https://aws.amazon.com/)
2. [AWS CLI](https://aws.amazon.com/cli/) installed and configured
3. [Docker](https://docs.docker.com/get-docker/) installed
## Step 1: Initial Setup
### Install and Configure AWS CLI
```bash macOS theme={null}
# Using Homebrew
brew install awscli
# Configure AWS CLI
aws configure
# Configure Docker for ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com
```
```bash Linux theme={null}
# Install AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Configure AWS CLI
aws configure
# Configure Docker for ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com
```
```powershell Windows theme={null}
# Download and run the AWS CLI MSI installer
# https://awscli.amazonaws.com/AWSCLIV2.msi
# Configure AWS CLI
aws configure
# Configure Docker for ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $(aws sts get-caller-identity --query Account --output text).dkr.ecr.us-east-1.amazonaws.com
```
## Step 2: Set Up AWS Infrastructure
### Connect existing S3 buckets
CaseBender uses customer-owned object storage. It does not create, empty, or
delete S3 buckets. Provision separate `quarantine`, `records`, and `ephemeral`
buckets (or equivalently isolated prefixes) before this deployment, then attach
an ECS task role or IRSA identity with scoped object permissions. Do not create
an IAM user or long-lived access key for a new deployment.
The canonical runtime variables are `STORAGE_PROVIDER=s3`, `S3_BUCKET`, and
`AWS_REGION`. `AWS_S3_BUCKET` and `AWS_S3_REGION` are not valid storage
variables. Prefer a mounted `STORAGE_CONFIG_FILE` when the three profiles use
different buckets.
See [Enterprise Storage Overview](/en/deployment/storage-overview) and
[Storage Security Baseline](/en/deployment/storage-security-baseline).
### Create a VPC
```bash theme={null}
# Create VPC
aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=casebender-vpc}]'
# Enable DNS hostnames
aws ec2 modify-vpc-attribute \
--vpc-id \
--enable-dns-hostnames
```
### Create Subnets
```bash theme={null}
# Create public subnets
aws ec2 create-subnet \
--vpc-id \
--cidr-block 10.0.1.0/24 \
--availability-zone us-east-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=casebender-public-1a}]'
aws ec2 create-subnet \
--vpc-id \
--cidr-block 10.0.2.0/24 \
--availability-zone us-east-1b \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=casebender-public-1b}]'
```
### Set Up RDS (PostgreSQL)
```bash theme={null}
# Create DB subnet group
aws rds create-db-subnet-group \
--db-subnet-group-name casebender-db-subnet \
--db-subnet-group-description "Subnet group for CaseBender RDS" \
--subnet-ids "" ""
# Create RDS instance
aws rds create-db-instance \
--db-instance-identifier casebender-db \
--db-instance-class db.t3.medium \
--engine postgres \
--master-username superadmin \
--master-user-password \
--allocated-storage 20 \
--db-subnet-group-name casebender-db-subnet
```
### Set Up ElastiCache (Redis)
```bash theme={null}
# Create cache subnet group
aws elasticache create-cache-subnet-group \
--cache-subnet-group-name casebender-cache-subnet \
--cache-subnet-group-description "Subnet group for CaseBender Redis" \
--subnet-ids "" ""
# Create Redis cluster
aws elasticache create-cache-cluster \
--cache-cluster-id casebender-redis \
--engine redis \
--cache-node-type cache.t3.micro \
--num-cache-nodes 1 \
--cache-subnet-group-name casebender-cache-subnet
```
## Step 3: Create ECR Repositories
```bash theme={null}
# Create repositories for each service
aws ecr create-repository --repository-name casebender/app
aws ecr create-repository --repository-name casebender/workflow-processor
aws ecr create-repository --repository-name casebender/misp-processor
# Get the AWS account ID
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
# Pull CaseBender images
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/misp-processor:latest
# Tag images for ECR
docker tag casebender/casebender:latest ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/app:latest
docker tag casebender/workflow-processor:latest ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/workflow-processor:latest
docker tag casebender/misp-processor:latest ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/misp-processor:latest
# Push images to ECR
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/app:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/workflow-processor:latest
docker push ${AWS_ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/casebender/misp-processor:latest
```
## Step 4: Create ECS Cluster
```bash theme={null}
# Create ECS cluster
aws ecs create-cluster --cluster-name casebender-cluster
# Create task execution role
aws iam create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document file://task-execution-assume-role.json
# Attach policy
aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
```
Create the audit-chain key once in AWS Secrets Manager. Preserve the existing
secret on every subsequent deployment:
```bash theme={null}
if ! aws secretsmanager describe-secret \
--secret-id casebender/AUDIT_INTEGRITY_SECRET >/dev/null 2>&1; then
aws secretsmanager create-secret \
--name casebender/AUDIT_INTEGRITY_SECRET \
--secret-string "$(openssl rand -hex 32)"
fi
```
Grant the ECS task execution role permission to read this secret, and inject it
into the `web`, `api`, and `worker` task definitions.
## Step 5: Create Task Definitions
Create task definition JSON files for each service:
```json theme={null}
{
"family": "casebender-app",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "1024",
"memory": "2048",
"executionRoleArn": "arn:aws:iam:::role/ecsTaskExecutionRole",
"containerDefinitions": [
{
"name": "app",
"image": ".dkr.ecr.us-east-1.amazonaws.com/casebender/app:latest",
"portMappings": [
{
"containerPort": 3000,
"protocol": "tcp"
}
],
"environment": [
{
"name": "POSTGRES_PRISMA_URL",
"value": "postgresql://superadmin:password@casebender-db.xxxxx.region.rds.amazonaws.com:5432/casebender"
},
{
"name": "REDIS_URL",
"value": "redis://casebender-redis.xxxxx.region.cache.amazonaws.com:6379"
},
{
"name": "STORAGE_PROVIDER",
"value": "s3"
},
{
"name": "S3_BUCKET",
"value": "casebender-storage"
},
{
"name": "AWS_REGION",
"value": "us-east-1"
}
],
"secrets": [
{
"name": "AUTH_SECRET",
"valueFrom": "arn:aws:secretsmanager:region:account:secret:auth-secret"
},
{
"name": "AUTH_SALT",
"valueFrom": "arn:aws:secretsmanager:region:account:secret:auth-salt"
},
{
"name": "AUDIT_INTEGRITY_SECRET",
"valueFrom": "arn:aws:secretsmanager:region:account:secret:casebender/AUDIT_INTEGRITY_SECRET"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/casebender",
"awslogs-region": "us-east-1",
"awslogs-stream-prefix": "app"
}
}
}
]
}
```
Register the task definitions:
```bash theme={null}
# Register task definitions
aws ecs register-task-definition --cli-input-json file://app-task-definition.json
aws ecs register-task-definition --cli-input-json file://workflow-processor-task-definition.json
aws ecs register-task-definition --cli-input-json file://misp-processor-task-definition.json
```
## Step 6: Create Application Load Balancer
```bash theme={null}
# Create ALB
aws elbv2 create-load-balancer \
--name casebender-alb \
--subnets \
--security-groups
# Create target group
aws elbv2 create-target-group \
--name casebender-tg \
--protocol HTTP \
--port 3000 \
--vpc-id \
--target-type ip
# Create listener
aws elbv2 create-listener \
--load-balancer-arn \
--protocol HTTPS \
--port 443 \
--certificates CertificateArn= \
--default-actions Type=forward,TargetGroupArn=
```
## Step 7: Create ECS Services
```bash theme={null}
# Create service for main app
aws ecs create-service \
--cluster casebender-cluster \
--service-name casebender-app \
--task-definition casebender-app \
--desired-count 2 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[,],securityGroups=[],assignPublicIp=ENABLED}" \
--load-balancers "targetGroupArn=,containerName=app,containerPort=3000"
# Create services for processors
aws ecs create-service \
--cluster casebender-cluster \
--service-name workflow-processor \
--task-definition casebender-workflow-processor \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[,],securityGroups=[],assignPublicIp=ENABLED}"
aws ecs create-service \
--cluster casebender-cluster \
--service-name misp-processor \
--task-definition casebender-misp-processor \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[,],securityGroups=[],assignPublicIp=ENABLED}"
```
## Step 8: Set Up Route 53 (Optional)
If you're using a custom domain:
```bash theme={null}
# Create hosted zone (if not exists)
aws route53 create-hosted-zone \
--name yourdomain.com \
--caller-reference $(date +%s)
# Create A record
aws route53 change-resource-record-sets \
--hosted-zone-id \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "yourdomain.com",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "",
"DNSName": "",
"EvaluateTargetHealth": true
}
}
}]
}'
```
## Monitoring and Maintenance
### Set Up CloudWatch Alarms
```bash theme={null}
# Create CPU utilization alarm
aws cloudwatch put-metric-alarm \
--alarm-name casebender-cpu-alarm \
--alarm-description "CPU utilization exceeded 80%" \
--metric-name CPUUtilization \
--namespace AWS/ECS \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=ClusterName,Value=casebender-cluster \
--evaluation-periods 2 \
--alarm-actions
```
### View Logs
```bash theme={null}
# View service logs
aws logs get-log-events \
--log-group-name /ecs/casebender \
--log-stream-name app/
```
### Update Services
```bash theme={null}
# Update service with new task definition
aws ecs update-service \
--cluster casebender-cluster \
--service casebender-app \
--task-definition casebender-app:NEW_REVISION
```
## Cost Optimization
1. Use Fargate Spot for non-critical workloads
2. Implement auto-scaling based on metrics
3. Choose appropriate instance sizes
4. Use Reserved Instances for predictable workloads
## Security Best Practices
1. Use AWS Secrets Manager for sensitive data
2. Implement WAF rules
3. Enable VPC Flow Logs
4. Regular security group audits
5. Enable AWS GuardDuty
## Next Steps
* Set up CI/CD pipeline with AWS CodePipeline
* Configure backup strategies
* Implement monitoring and alerting
* Review security best practices
# Deploy to Azure
Source: https://docs.casebender.com/en/deployment/azure
Deploy CaseBender on Microsoft Azure
Reference architecture only. This page is not a production-certified deployment
procedure and predates the current activation, image-pinning, secret-management,
and network-isolation baseline. Use the [supported on-premises guide](/en/quickstart)
or complete an enterprise architecture review before deployment.
## Overview
This guide walks you through deploying CaseBender on Azure using pre-built Docker images with Azure Container Apps and managed services.
## Prerequisites
1. [Azure Account](https://azure.microsoft.com/)
2. [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) installed
3. [Docker](https://docs.docker.com/get-docker/) installed
## Step 1: Initial Setup
### Install and Configure Azure CLI
```bash macOS theme={null}
# Using Homebrew
brew install azure-cli
# Login to Azure
az login
# Configure Docker for ACR
az acr login --name casebenderacr
```
```bash Linux theme={null}
# Install Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# Login to Azure
az login
# Configure Docker for ACR
az acr login --name casebenderacr
```
```powershell Windows theme={null}
# Using winget
winget install -e --id Microsoft.AzureCLI
# Login to Azure
az login
# Configure Docker for ACR
az acr login --name casebenderacr
```
### Initialize Project
```bash theme={null}
# Set variables
RESOURCE_GROUP="casebender-rg"
LOCATION="eastus"
# Create resource group
az group create --name $RESOURCE_GROUP --location $LOCATION
# Enable required services
az provider register --namespace Microsoft.ContainerRegistry
az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.Storage
```
## Step 2: Set Up Azure Infrastructure
### Connect existing Blob storage
CaseBender uses customer-owned private Blob containers. It does not create,
configure, empty, or delete storage accounts or containers. Provision separate
`quarantine`, `records`, and `ephemeral` containers before this deployment.
Azure Blob code is implemented under canonical provider ID `azure`. It is not currently declared release-supported in
`scripts/storage/certification-matrix.json`. Complete live qualification before
making a production support claim.
Use a system-assigned or user-assigned Managed Identity through
`DefaultAzureCredential`. Assign `Storage Blob Data Contributor` only at the
required container scope. Do not list account keys or grant storage-account
administration.
```bash theme={null}
az storage account show \
--name casebenderstorage \
--resource-group $RESOURCE_GROUP
az storage container show \
--name casebender \
--account-name casebenderstorage \
--auth-mode login
az identity create \
--name casebender-storage-identity \
--resource-group $RESOURCE_GROUP
IDENTITY_ID=$(az identity show \
--name casebender-storage-identity \
--resource-group $RESOURCE_GROUP \
--query id -o tsv)
STORAGE_ACCOUNT_ID="$(az storage account show \
--name casebenderstorage \
--resource-group $RESOURCE_GROUP \
--query id -o tsv)"
az role assignment create \
--assignee-object-id $(az identity show --name casebender-storage-identity --resource-group $RESOURCE_GROUP --query principalId -o tsv) \
--assignee-principal-type ServicePrincipal \
--role "Storage Blob Data Contributor" \
--scope "${STORAGE_ACCOUNT_ID}/blobServices/default/containers/casebender"
```
The canonical runtime variables are `STORAGE_PROVIDER=azure`,
`AZURE_STORAGE_ACCOUNT`, and `AZURE_CONTAINER`. `azure-blob` and
`AZURE_STORAGE_CONTAINER` are invalid runtime names.
See [Enterprise Storage Overview](/en/deployment/storage-overview) and
[Storage Security Baseline](/en/deployment/storage-security-baseline).
### Set Up Azure Database for PostgreSQL
```bash theme={null}
# Create PostgreSQL server
az postgres flexible-server create \
--resource-group $RESOURCE_GROUP \
--name casebender-db \
--admin-user superadmin \
--admin-password \
--sku-name Standard_B2s \
--storage-size 32 \
--version 14
# Create database
az postgres flexible-server db create \
--resource-group $RESOURCE_GROUP \
--server-name casebender-db \
--database-name casebender
```
### Set Up Azure Cache for Redis
```bash theme={null}
# Create Redis cache
az redis create \
--resource-group $RESOURCE_GROUP \
--name casebender-redis \
--sku Basic \
--vm-size c0 \
--location $LOCATION
```
## Step 3: Create and Configure Container Registry
```bash theme={null}
# Create Azure Container Registry
az acr create \
--resource-group $RESOURCE_GROUP \
--name casebenderacr \
--sku Standard \
--admin-enabled true
# Get registry credentials
ACR_USERNAME=$(az acr credential show --name casebenderacr --query username -o tsv)
ACR_PASSWORD=$(az acr credential show --name casebenderacr --query "passwords[0].value" -o tsv)
# Pull CaseBender images
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/misp-processor:latest
# Tag images for ACR
docker tag casebender/casebender:latest casebenderacr.azurecr.io/casebender/app:latest
docker tag casebender/workflow-processor:latest casebenderacr.azurecr.io/casebender/workflow-processor:latest
docker tag casebender/misp-processor:latest casebenderacr.azurecr.io/casebender/misp-processor:latest
# Push images to ACR
docker push casebenderacr.azurecr.io/casebender/app:latest
docker push casebenderacr.azurecr.io/casebender/workflow-processor:latest
docker push casebenderacr.azurecr.io/casebender/misp-processor:latest
```
## Step 4: Deploy Services
### Create Container Apps Environment
```bash theme={null}
# Create Container Apps environment
az containerapp env create \
--name casebender-env \
--resource-group $RESOURCE_GROUP \
--location $LOCATION
# Create main application
az containerapp create \
--name casebender-app \
--resource-group $RESOURCE_GROUP \
--environment casebender-env \
--image casebenderacr.azurecr.io/casebender/app:latest \
--target-port 3000 \
--ingress external \
--registry-server casebenderacr.azurecr.io \
--registry-username $ACR_USERNAME \
--registry-password $ACR_PASSWORD \
--user-assigned-identity $IDENTITY_ID \
--env-vars \
AUTH_SECRET= \
AUTH_SALT= \
POSTGRES_PRISMA_URL="postgresql://superadmin:@casebender-db.postgres.database.azure.com:5432/casebender" \
REDIS_URL="redis://casebender-redis.redis.cache.windows.net:6380?ssl=true&password=" \
STORAGE_PROVIDER="azure" \
AZURE_STORAGE_ACCOUNT="casebenderstorage" \
AZURE_CONTAINER="casebender"
# Create workflow processor
az containerapp create \
--name workflow-processor \
--resource-group $RESOURCE_GROUP \
--environment casebender-env \
--image casebenderacr.azurecr.io/casebender/workflow-processor:latest \
--registry-server casebenderacr.azurecr.io \
--registry-username $ACR_USERNAME \
--registry-password $ACR_PASSWORD \
--min-replicas 1 \
--max-replicas 1 \
--env-vars \
POSTGRES_PRISMA_URL="postgresql://superadmin:@casebender-db.postgres.database.azure.com:5432/casebender" \
REDIS_URL="redis://casebender-redis.redis.cache.windows.net:6380?ssl=true&password="
# Create MISP processor
az containerapp create \
--name misp-processor \
--resource-group $RESOURCE_GROUP \
--environment casebender-env \
--image casebenderacr.azurecr.io/casebender/misp-processor:latest \
--registry-server casebenderacr.azurecr.io \
--registry-username $ACR_USERNAME \
--registry-password $ACR_PASSWORD \
--min-replicas 1 \
--max-replicas 1 \
--env-vars \
POSTGRES_PRISMA_URL="postgresql://superadmin:@casebender-db.postgres.database.azure.com:5432/casebender" \
REDIS_URL="redis://casebender-redis.redis.cache.windows.net:6380?ssl=true&password="
```
## Step 5: Set Up Azure Front Door
```bash theme={null}
# Create Front Door profile
az afd profile create \
--profile-name casebender-afd \
--resource-group $RESOURCE_GROUP \
--sku Standard_AzureFrontDoor
# Create endpoint
az afd endpoint create \
--endpoint-name casebender \
--profile-name casebender-afd \
--resource-group $RESOURCE_GROUP
# Create origin group
az afd origin-group create \
--origin-group-name casebender-origin-group \
--profile-name casebender-afd \
--resource-group $RESOURCE_GROUP \
--probe-path "/" \
--probe-protocol Http \
--probe-request-type GET
# Add origin
az afd origin create \
--origin-group-name casebender-origin-group \
--origin-name casebender-origin \
--profile-name casebender-afd \
--resource-group $RESOURCE_GROUP \
--host-name \
--origin-host-header \
--priority 1 \
--weight 1000 \
--enabled-state Enabled
```
## Step 6: Configure Custom Domain (Optional)
```bash theme={null}
# Add custom domain to Front Door
az afd custom-domain create \
--custom-domain-name casebender-domain \
--host-name your-domain.com \
--profile-name casebender-afd \
--resource-group $RESOURCE_GROUP \
--minimum-tls-version TLS12
# Enable HTTPS
az afd custom-domain enable-https \
--custom-domain-name casebender-domain \
--profile-name casebender-afd \
--resource-group $RESOURCE_GROUP
```
## Monitoring and Maintenance
### Set Up Application Insights
```bash theme={null}
# Create Application Insights
az monitor app-insights component create \
--app casebender-insights \
--location $LOCATION \
--resource-group $RESOURCE_GROUP \
--application-type web
# Get instrumentation key
az monitor app-insights component show \
--app casebender-insights \
--resource-group $RESOURCE_GROUP \
--query instrumentationKey \
--output tsv
```
### Configure Alerts
```bash theme={null}
# Create action group
az monitor action-group create \
--name casebender-alerts \
--resource-group $RESOURCE_GROUP \
--action email admin email@yourdomain.com
# Create alert rule
az monitor metrics alert create \
--name "high-cpu-usage" \
--resource-group $RESOURCE_GROUP \
--scopes \
--condition "avg CPU > 80" \
--window-size 5m \
--evaluation-frequency 1m \
--action
```
### View Logs
```bash theme={null}
# View container app logs
az containerapp logs show \
--name casebender-app \
--resource-group $RESOURCE_GROUP \
--follow
```
## Scaling Configuration
```bash theme={null}
# Configure scaling rules
az containerapp update \
--name casebender-app \
--resource-group $RESOURCE_GROUP \
--min-replicas 1 \
--max-replicas 10 \
--scale-rule-name http-rule \
--scale-rule-type http \
--scale-rule-http-concurrency 50
```
## Backup and Disaster Recovery
### Configure Database Backups
```bash theme={null}
# Enable automated backups
az postgres flexible-server update \
--resource-group $RESOURCE_GROUP \
--name casebender-db \
--backup-retention 7
```
### Configure Geo-Replication
```bash theme={null}
# Create secondary region resources
az postgres flexible-server replica create \
--name casebender-db-secondary \
--source-server casebender-db \
--resource-group $RESOURCE_GROUP \
--location westus
```
## Security Best Practices
1. Enable Azure Defender for all services
2. Implement Azure Private Link
3. Use Managed Identities
4. Regular security assessments
5. Enable diagnostic logging
## Cost Optimization
1. Use consumption plan for Container Apps
2. Implement auto-scaling rules
3. Choose appropriate service tiers
4. Monitor usage patterns
5. Use Azure Reserved Instances
## Next Steps
* Set up CI/CD with Azure DevOps
* Implement comprehensive monitoring
* Configure disaster recovery
* Review security compliance
# Desktop Installer
Source: https://docs.casebender.com/en/deployment/desktop-installer
One-click installer for deploying CaseBender locally
The CaseBender Desktop Installer is the easiest way to deploy CaseBender on your local machine. It handles Docker setup, configuration, and service management automatically.
An installation that currently has an installer-generated `docker-compose.yml`
with `app`, `db`, and MinIO services must not be converted by copying
`docker-compose.prod.yml` over it. Follow
[Migrate a Legacy Docker Compose Installation](/en/deployment/legacy-compose-migration)
to preserve PostgreSQL, attachments, license state, and encryption keys.
## Download Installer
The installer automatically detects your system and configures CaseBender with optimal settings.
**For Apple Silicon (M1/M2/M3) and Intel Macs**
Recommended for M1/M2/M3 Macs
For Intel-based Macs
**Installation:**
1. Download the DMG file for your Mac
2. Open the DMG and drag CaseBender Installer to Applications
3. Launch from Applications folder
4. If prompted about unidentified developer, right-click and select "Open"
**For Windows 10/11 (64-bit)**
Recommended installer with auto-updates
No installation required
**Installation:**
1. Download the installer
2. Run the installer (you may need to click "More info" → "Run anyway" if Windows SmartScreen appears)
3. Follow the installation wizard
4. Launch CaseBender Installer from the Start menu
**For Ubuntu, Debian, and other distributions**
Works on most Linux distributions
For Debian/Ubuntu-based systems
**Installation (AppImage):**
```bash theme={null}
chmod +x CaseBender-Installer.AppImage
./CaseBender-Installer.AppImage
```
**Installation (DEB):**
```bash theme={null}
sudo dpkg -i CaseBender-Installer.deb
sudo apt-get install -f # Install dependencies if needed
```
## System Requirements
| Component | Minimum | Recommended |
| -------------- | ---------------------------------------- | ----------- |
| **RAM** | 8 GB | 16 GB |
| **Disk Space** | 10 GB | 20 GB |
| **Docker** | 20.10+ | Latest |
| **OS** | macOS 10.15+, Windows 10+, Ubuntu 20.04+ | Latest LTS |
Docker Desktop must be installed and running before using the CaseBender Installer. The installer will guide you through Docker installation if it's not detected.
## Features
Deploy CaseBender with a single click. No command line required.
Automatically generates secure credentials and SSL certificates.
Start, stop, and monitor all CaseBender services from a unified dashboard.
Update to a signed, version-pinned release with one click.
## What Gets Installed
The installer deploys the following services:
* **CaseBender Web App** - Main application
* **PostgreSQL** - Database
* **Redis** - Authenticated cache and message queue
* **OpenSearch** - Authenticated search service
* **Workflow Processor** - Background job processing
* **MISP Processor** - Threat intelligence integration
* **File storage** - Named Docker volume plus bundled ClamAV by default;
optional customer-owned S3, GCS, Azure, or qualified S3-compatible storage.
Independent of community vs enterprise license. The installer does not deploy MinIO
* **Nginx** - The only host-facing service (ports 80 and 443)
Application and data-service ports stay on the private Docker network.
## First Launch
After installation:
1. **Start Docker Desktop** - Ensure Docker is running
2. **Launch the Installer** - Open CaseBender Installer
3. **Click "Install"** - The installer will pull images and configure services
4. **Access CaseBender** - Open `https://local.casebender.com` in your browser
5. **Complete activation** - Follow the local `/setup` page to create the first
administrator
The activation page is served by your own CaseBender installation. It does not
require CaseBender to be reachable from the public internet.
## First administrator
The installer generates installation-specific infrastructure secrets. The
audit-chain key is persisted as `secret/audit_integrity_secret` and recovered
from an existing `.env` during upgrades; preserve both with the installation
backup and never rotate the key during a routine update. The installer does not
create a shared production administrator password.
Use the short-lived code displayed by the installer on the `/setup` page, then
choose the administrator email and password. Store the password in your
enterprise password manager and enroll MFA. See
[First-run setup](/en/deployment/first-run-setup).
## Troubleshooting
### Docker Not Found
If the installer can't find Docker:
1. Install [Docker Desktop](https://www.docker.com/products/docker-desktop/)
2. Start Docker Desktop
3. Wait for Docker to fully initialize (green icon in system tray)
4. Restart the CaseBender Installer
### Port Conflicts
If you see port conflict errors:
1. Check which application is using the port: `lsof -i :PORT` (macOS/Linux) or `netstat -ano | findstr :PORT` (Windows)
2. Stop the conflicting application
3. Retry the installation
### macOS Gatekeeper Warning
If macOS blocks the app:
1. Right-click (or Control+click) on the app
2. Select "Open" from the context menu
3. Click "Open" in the dialog
### Windows SmartScreen
If Windows blocks the installer:
1. Click "More info"
2. Click "Run anyway"
## Manual Installation
If you prefer manual installation or need more control, see the [Quickstart Guide](/en/quickstart) for Docker Compose setup instructions.
## All Releases
Community installers are published through the public CaseBender download links
above, not through the private source repository. Production operators should
archive the exact installer, checksum, and image manifest used for each
deployment.
# Deploy to DigitalOcean
Source: https://docs.casebender.com/en/deployment/digitalocean
Deploy CaseBender on DigitalOcean
Reference architecture only. This page is not a production-certified deployment
procedure and predates the current activation, image-pinning, secret-management,
and network-isolation baseline. Use the [supported on-premises guide](/en/quickstart)
or complete an enterprise architecture review before deployment.
## Overview
This guide walks you through deploying CaseBender on DigitalOcean using pre-built Docker images with Kubernetes (DOKS) and managed services.
## Prerequisites
1. [DigitalOcean Account](https://cloud.digitalocean.com/)
2. [doctl](https://docs.digitalocean.com/reference/doctl/how-to/install/) CLI installed
3. [kubectl](https://kubernetes.io/docs/tasks/tools/) installed
4. [Docker](https://docs.docker.com/get-docker/) installed
## Step 1: Initial Setup
### Install and Configure doctl
```bash macOS theme={null}
# Using Homebrew
brew install doctl
# Authenticate with API token
doctl auth init
# Configure Docker for Container Registry
doctl registry login
```
```bash Linux theme={null}
# Download latest release
cd ~/Downloads
wget https://github.com/digitalocean/doctl/releases/download/v1.XX.X/doctl-1.XX.X-linux-amd64.tar.gz
# Extract and move to path
tar xf ~/Downloads/doctl-1.XX.X-linux-amd64.tar.gz
sudo mv ~/Downloads/doctl /usr/local/bin
# Authenticate with API token
doctl auth init
# Configure Docker for Container Registry
doctl registry login
```
```powershell Windows theme={null}
# Using Chocolatey
choco install doctl
# Authenticate with API token
doctl auth init
# Configure Docker for Container Registry
doctl registry login
```
## Step 2: Create Kubernetes Cluster
```bash theme={null}
# Create DOKS cluster
doctl kubernetes cluster create casebender \
--region nyc1 \
--size s-2vcpu-4gb \
--count 3 \
--version latest
# Get kubeconfig
doctl kubernetes cluster kubeconfig save casebender
```
## Step 3: Set Up Managed Services
### Create Spaces for Object Storage
```bash theme={null}
# Create Spaces bucket
doctl spaces create casebender-storage \
--region nyc3
# Create Spaces access key
doctl spaces access-key create
# Note: Save the access key and secret key securely
# They will be needed for application configuration
```
### Create Managed PostgreSQL
```bash theme={null}
# Create database cluster
doctl databases create \
--engine pg \
--name casebender-db \
--region nyc1 \
--size db-s-2vcpu-4gb \
--version 14 \
--num-nodes 1
# Create database
doctl databases db create casebender-db casebender
# Get connection details
doctl databases connection casebender-db --format ConnectionString
```
### Create Managed Redis
```bash theme={null}
# Create Redis cluster
doctl databases create \
--engine redis \
--name casebender-redis \
--region nyc1 \
--size db-s-1vcpu-2gb \
--version 7
# Get connection details
doctl databases connection casebender-redis --format ConnectionString
```
## Step 4: Configure Container Registry
```bash theme={null}
# Create container registry
doctl registry create casebender-registry
# Get registry endpoint
REGISTRY_ENDPOINT=$(doctl registry get-endpoint)
# Pull CaseBender images
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/misp-processor:latest
# Tag images for registry
docker tag casebender/casebender:latest registry.digitalocean.com/casebender-registry/app:latest
docker tag casebender/workflow-processor:latest registry.digitalocean.com/casebender-registry/workflow-processor:latest
docker tag casebender/misp-processor:latest registry.digitalocean.com/casebender-registry/misp-processor:latest
# Push images
docker push registry.digitalocean.com/casebender-registry/app:latest
docker push registry.digitalocean.com/casebender-registry/workflow-processor:latest
docker push registry.digitalocean.com/casebender-registry/misp-processor:latest
# Add registry to Kubernetes cluster
doctl kubernetes cluster registry add casebender
```
## Step 5: Deploy to Kubernetes
### Create Namespace
```bash theme={null}
kubectl create namespace casebender
```
### Create Secrets
```bash theme={null}
# Create secrets for database and Redis
kubectl create secret generic db-credentials \
--namespace casebender \
--from-literal=postgres-url="postgresql://doadmin:password@casebender-db-do-user-1234567-0.b.db.ondigitalocean.com:25060/casebender?sslmode=require" \
--from-literal=redis-url="rediss://default:password@casebender-redis-do-user-1234567-0.b.db.ondigitalocean.com:25061"
# Create secrets for application
kubectl create secret generic app-secrets \
--namespace casebender \
--from-literal=auth-secret="your-auth-secret" \
--from-literal=auth-salt="your-auth-salt"
```
### Deploy Applications
Create `deployment.yaml`:
```yaml theme={null}
apiVersion: apps/v1
kind: Deployment
metadata:
name: casebender-app
namespace: casebender
spec:
replicas: 2
selector:
matchLabels:
app: casebender-app
template:
metadata:
labels:
app: casebender-app
spec:
containers:
- name: app
image: registry.digitalocean.com/casebender-registry/app:latest
ports:
- containerPort: 3000
env:
- name: AUTH_SECRET
valueFrom:
secretKeyRef:
name: app-secrets
key: auth-secret
- name: AUTH_SALT
valueFrom:
secretKeyRef:
name: app-secrets
key: auth-salt
- name: POSTGRES_PRISMA_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: postgres-url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: redis-url
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: workflow-processor
namespace: casebender
spec:
replicas: 1
selector:
matchLabels:
app: workflow-processor
template:
metadata:
labels:
app: workflow-processor
spec:
containers:
- name: processor
image: registry.digitalocean.com/casebender-registry/workflow-processor:latest
env:
- name: POSTGRES_PRISMA_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: postgres-url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: redis-url
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: misp-processor
namespace: casebender
spec:
replicas: 1
selector:
matchLabels:
app: misp-processor
template:
metadata:
labels:
app: misp-processor
spec:
containers:
- name: processor
image: registry.digitalocean.com/casebender-registry/misp-processor:latest
env:
- name: POSTGRES_PRISMA_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: postgres-url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: redis-url
```
Apply the deployments:
```bash theme={null}
kubectl apply -f deployment.yaml
```
### Create Services
Create `service.yaml`:
```yaml theme={null}
apiVersion: v1
kind: Service
metadata:
name: casebender-app
namespace: casebender
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 3000
selector:
app: casebender-app
```
Apply the service:
```bash theme={null}
kubectl apply -f service.yaml
```
## Step 7: Set Up Ingress
### Install NGINX Ingress Controller
```bash theme={null}
# Add Helm repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Install NGINX Ingress Controller
helm install nginx-ingress ingress-nginx/ingress-nginx \
--namespace casebender \
--set controller.publishService.enabled=true
```
### Configure Ingress
Create `ingress.yaml`:
```yaml theme={null}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: casebender-ingress
namespace: casebender
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- your-domain.com
secretName: casebender-tls
rules:
- host: your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: casebender-app
port:
number: 80
```
Apply the ingress:
```bash theme={null}
kubectl apply -f ingress.yaml
```
## Step 8: Set Up SSL with cert-manager
```bash theme={null}
# Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.8.0/cert-manager.yaml
# Create ClusterIssuer
cat <
Reference architecture only. This page is not a production-certified deployment
procedure and predates the current activation, image-pinning, secret-management,
and network-isolation baseline. Use the [supported on-premises guide](/en/quickstart)
or complete an enterprise architecture review before deployment.
The repository deployment workflows now build and deploy the complete service
set, including the private, always-on `casebender-connector-worker`. See
[Integration Execution Plane](/en/deployment/integration-execution-plane) for
its required secrets, queue contract, and health checks.
## Overview
This guide walks you through deploying CaseBender on Google Cloud Run using our pre-built Docker images.
## Prerequisites
1. [Google Cloud Account](https://cloud.google.com/)
2. [Google Cloud CLI](https://cloud.google.com/sdk/docs/install) installed
3. [Docker](https://docs.docker.com/get-docker/) installed
## Step 1: Initial Setup
### Install Google Cloud CLI
```bash macOS theme={null}
# Using Homebrew
brew install google-cloud-sdk
# Login to Google Cloud
gcloud auth login
# Configure Docker to use Google Cloud
gcloud auth configure-docker
```
```bash Linux theme={null}
# Download the archive
curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-VERSION-linux-x86_64.tar.gz
# Extract the archive
tar -xf google-cloud-cli-VERSION-linux-x86_64.tar.gz
# Run the install script
./google-cloud-sdk/install.sh
# Login to Google Cloud
gcloud auth login
# Configure Docker to use Google Cloud
gcloud auth configure-docker
```
```powershell Windows theme={null}
# Download and run the installer
# https://dl.google.com/dl/cloudsdk/channels/rapid/GoogleCloudSDKInstaller.exe
# Login to Google Cloud
gcloud auth login
# Configure Docker to use Google Cloud
gcloud auth configure-docker
```
### Initialize Project
```bash theme={null}
# Set your project ID
gcloud config set project YOUR_PROJECT_ID
# Enable required APIs
gcloud services enable \
cloudbuild.googleapis.com \
run.googleapis.com \
secretmanager.googleapis.com \
cloudresourcemanager.googleapis.com \
artifactregistry.googleapis.com
```
## Step 2: Set Up Cloud Infrastructure
### Connect existing Cloud Storage buckets
CaseBender uses customer-owned GCS buckets. It does not create, empty, or
delete buckets. Provision separate `quarantine`, `records`, and `ephemeral`
buckets before this deployment.
Use Cloud Run service identity or GKE Workload Identity with Application
Default Credentials. Do not download a service-account key for a new production
deployment.
```bash theme={null}
gcloud storage buckets describe gs://casebender-storage
gcloud iam service-accounts create casebender-storage \
--display-name "CaseBender Storage Service Account"
STORAGE_SA_EMAIL=$(gcloud iam service-accounts list \
--filter="displayName:CaseBender Storage Service Account" \
--format="value(email)")
gcloud storage buckets add-iam-policy-binding gs://casebender-storage \
--member="serviceAccount:${STORAGE_SA_EMAIL}" \
--role="roles/storage.objectUser"
```
The canonical runtime variables are `STORAGE_PROVIDER=gcs`, `GCS_BUCKET`, and
optional `GCS_PROJECT_ID`. `GOOGLE_STORAGE_BUCKET` is not a CaseBender storage
variable.
See [Enterprise Storage Overview](/en/deployment/storage-overview) and
[Storage Security Baseline](/en/deployment/storage-security-baseline).
### Set Up Cloud SQL (PostgreSQL)
```bash theme={null}
# Create PostgreSQL instance
gcloud sql instances create casebender-db \
--database-version=POSTGRES_14 \
--cpu=2 \
--memory=4GB \
--region=us-central1 \
--root-password="YOUR_SECURE_PASSWORD"
# Create database
gcloud sql databases create casebender \
--instance=casebender-db
# Create user
gcloud sql users create casebender \
--instance=casebender-db \
--password="YOUR_SECURE_PASSWORD"
```
### Set Up Memorystore (Redis)
```bash theme={null}
# Create Redis instance
gcloud redis instances create casebender-redis \
--size=2 \
--region=us-central1 \
--redis-version=redis_6_x
```
### Configure Secret Manager
CaseBender's `web`, `api`, and `worker` services require one stable
`AUDIT_INTEGRITY_SECRET` to authenticate the tamper-evident audit chain. Create
it once, grant the runtime service account access, and bind the same secret to
all three services. Never replace it during a normal deployment.
The repository's `deploy/gcloud/setup-infrastructure.sh` and
`deploy-gcloud.yml` workflow create the secret only when it is absent and
preserve existing values. For a manual deployment:
```bash theme={null}
PROJECT_NUMBER="$(gcloud projects describe "$PROJECT_ID" --format='value(projectNumber)')"
RUNTIME_SA="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
if ! gcloud secrets describe AUDIT_INTEGRITY_SECRET >/dev/null 2>&1; then
openssl rand -hex 32 | tr -d '\n' |
gcloud secrets create AUDIT_INTEGRITY_SECRET --data-file=-
fi
gcloud secrets add-iam-policy-binding AUDIT_INTEGRITY_SECRET \
--member="serviceAccount:${RUNTIME_SA}" \
--role="roles/secretmanager.secretAccessor"
```
```bash theme={null}
# Create and store environment variables
cat << EOF | gcloud secrets create casebender-env --data-file=-
AUTH_SECRET=your-auth-secret
AUTH_SALT=your-auth-salt
POSTGRES_PRISMA_URL="postgresql://casebender:YOUR_SECURE_PASSWORD@/casebender?host=/cloudsql/YOUR_PROJECT_ID:us-central1:casebender-db"
REDIS_URL="redis://REDIS_IP_ADDRESS:6379"
STORAGE_PROVIDER=gcs
GCS_BUCKET=casebender-storage
EOF
```
## Step 3: Pull and Push Docker Images
```bash theme={null}
# Create Artifact Registry repository
gcloud artifacts repositories create casebender \
--repository-format=docker \
--location=us-central1
# Configure Docker for Artifact Registry
gcloud auth configure-docker us-central1-docker.pkg.dev
# Pull CaseBender images
docker pull casebender/casebender:latest
docker pull casebender/workflow-processor:latest
docker pull casebender/connector-worker:latest
docker pull casebender/misp-processor:latest
# Tag images for Google Artifact Registry
docker tag casebender/casebender:latest us-central1-docker.pkg.dev/$PROJECT_ID/casebender/app:latest
docker tag casebender/workflow-processor:latest us-central1-docker.pkg.dev/$PROJECT_ID/casebender/workflow-processor:latest
docker tag casebender/connector-worker:latest us-central1-docker.pkg.dev/$PROJECT_ID/casebender/connector-worker:latest
docker tag casebender/misp-processor:latest us-central1-docker.pkg.dev/$PROJECT_ID/casebender/misp-processor:latest
# Push images
docker push us-central1-docker.pkg.dev/$PROJECT_ID/casebender/app:latest
docker push us-central1-docker.pkg.dev/$PROJECT_ID/casebender/workflow-processor:latest
docker push us-central1-docker.pkg.dev/$PROJECT_ID/casebender/connector-worker:latest
docker push us-central1-docker.pkg.dev/$PROJECT_ID/casebender/misp-processor:latest
```
## Step 4: Deploy Services
### Deploy Main Application
```bash theme={null}
# Deploy to Cloud Run
gcloud run deploy casebender \
--image us-central1-docker.pkg.dev/$PROJECT_ID/casebender/app:latest \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars STORAGE_PROVIDER=gcs,GCS_BUCKET=casebender-storage \
--service-account=$STORAGE_SA_EMAIL \
--add-cloudsql-instances $PROJECT_ID:us-central1:casebender-db \
--set-secrets "AUDIT_INTEGRITY_SECRET=AUDIT_INTEGRITY_SECRET:latest,/app/.env=casebender-env:latest"
```
Apply the same `AUDIT_INTEGRITY_SECRET` binding to the API and worker
deployments. A missing binding does not necessarily fail a basic health probe;
it fails the first operation that must append a protected audit record.
### Configure authenticated Pub/Sub alert pushes
Pub/Sub must attach a Google-signed OIDC token when it pushes alerts to
`/api/pubsub/alerts`. Configure an exact audience and an allow-list that maps
each push service account to an existing organization and active organization
member. CaseBender uses the mapped member as the audit actor and always scopes
created alerts to the mapped organization.
```bash theme={null}
PUBSUB_AUDIENCE="https://casebender.example/api/pubsub/alerts"
PUBSUB_PUSH_SA="casebender-pubsub@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud pubsub subscriptions update casebender-alerts \
--push-endpoint="${PUBSUB_AUDIENCE}" \
--push-auth-service-account="${PUBSUB_PUSH_SA}" \
--push-auth-token-audience="${PUBSUB_AUDIENCE}"
```
Set these variables on the web service:
```dotenv theme={null}
PUBSUB_AUTH_MODE=required
PUBSUB_OIDC_AUDIENCE=https://casebender.example/api/pubsub/alerts
PUBSUB_PUSH_IDENTITY_MAPPINGS=[{"serviceAccountEmail":"casebender-pubsub@example-project.iam.gserviceaccount.com","organizationId":"replace-with-organization-id","systemUserEmail":"ingestion@example.com"}]
```
`PUBSUB_PUSH_IDENTITY_MAPPINGS` must be a JSON array. Service-account emails
must be unique, and every referenced organization and system user must already
exist. The system user must be active and belong to the mapped organization.
Requests with a missing, forged, expired, wrong-audience, or unlisted-identity
token are rejected before the message body is processed.
`PUBSUB_AUTH_MODE=disabled` is accepted only when `NODE_ENV` is `development`
or `test`, and it still requires exactly one organization mapping. Never set it
on a deployed service.
Include `AUDIT_INTEGRITY_SECRET` in the protected recovery inventory. Losing or
rotating it prevents verification of audit entries written with the previous
key.
### Deploy Workflow Processor
```bash theme={null}
# Deploy workflow processor
gcloud run deploy workflow-processor \
--image us-central1-docker.pkg.dev/$PROJECT_ID/casebender/workflow-processor:latest \
--platform managed \
--region us-central1 \
--no-allow-unauthenticated \
--service-account=$STORAGE_SA_EMAIL \
--add-cloudsql-instances $PROJECT_ID:us-central1:casebender-db \
--set-secrets "/app/.env=casebender-env:latest"
```
### Deploy Connector Worker
```bash theme={null}
gcloud run deploy casebender-connector-worker \
--image us-central1-docker.pkg.dev/$PROJECT_ID/casebender/connector-worker:latest \
--platform managed \
--region us-central1 \
--no-allow-unauthenticated \
--port 3015 \
--min-instances 1 \
--no-cpu-throttling \
--add-cloudsql-instances $PROJECT_ID:us-central1:casebender-db \
--set-secrets "POSTGRES_PRISMA_URL=POSTGRES_PRISMA_URL:latest,REDIS_URL=REDIS_URL:latest,CREDENTIAL_ENCRYPTION_KEY=CREDENTIAL_ENCRYPTION_KEY:latest" \
--set-env-vars "CONNECTOR_ACTION_QUEUE_NAME=connector-actions,CONNECTOR_ACTION_RESULT_QUEUE_NAME=connector-action-results,CONNECTOR_MOCK_DESTRUCTIVE=0"
```
### Deploy MISP Processor
```bash theme={null}
# Deploy MISP processor
gcloud run deploy misp-processor \
--image us-central1-docker.pkg.dev/$PROJECT_ID/casebender/misp-processor:latest \
--platform managed \
--region us-central1 \
--no-allow-unauthenticated \
--service-account=$STORAGE_SA_EMAIL \
--add-cloudsql-instances $PROJECT_ID:us-central1:casebender-db \
--set-secrets "/app/.env=casebender-env:latest"
```
## Step 5: Configure Domain and SSL
### Map Custom Domain
```bash theme={null}
# Add domain mapping
gcloud run domain-mappings create \
--service casebender \
--domain your-domain.com \
--region us-central1
```
Follow the DNS verification steps in the Google Cloud Console to complete domain mapping.
## Monitoring and Maintenance
### Set Up Monitoring
1. Navigate to Cloud Monitoring in Google Cloud Console
2. Create an uptime check for your service
3. Set up alerts for:
* Error rates
* Latency
* Instance count
* Memory usage
### View Logs
```bash theme={null}
# View service logs
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=casebender" --limit 50
# Stream logs
gcloud logging tail "resource.type=cloud_run_revision AND resource.labels.service_name=casebender"
```
### Update Application
To deploy updates:
```bash theme={null}
# Build and deploy new version
gcloud builds submit --config cloudbuild.yaml
# Roll back if needed
gcloud run services rollback casebender \
--to-revision=REVISION_ID \
--region=us-central1
```
## Cost Optimization
1. **Autoscaling Configuration**
```bash theme={null}
gcloud run services update casebender \
--min-instances=1 \
--max-instances=10 \
--region=us-central1
```
2. **Resource Allocation**
```bash theme={null}
gcloud run services update casebender \
--memory=1Gi \
--cpu=1 \
--region=us-central1
```
## Troubleshooting
### Common Issues
1. **Connection Issues**
* Verify Cloud SQL connection
* Check Redis connectivity
* Validate environment variables
2. **Performance Problems**
* Review instance metrics
* Check resource allocation
* Analyze request patterns
3. **Deployment Failures**
* Check build logs
* Verify service account permissions
* Review deployment configuration
4. **Seed did not run**
* Cloud Run web startup must call `ts-node --transpile-only` for `prisma/seed.ts`.
* Without `--transpile-only`, seed typechecks `console`/`process` and exits with
`Seed already run or failed (non-critical)` while the app still starts.
5. **Uploaded images stay on HTTP 409**
* `GET /attachment/{id}?ready=1` returns 409 until the worker marks the object
`CLEAN` and promotes it out of quarantine.
* Cloud Run has no ClamAV sidecar. The worker must set
`MALWARE_SCANNER_PROVIDER=skip`. Without it, logs show
`A supported external malware scanner must be configured` and uploads
never leave quarantine.
## Next Steps
* Set up CI/CD pipelines
* Configure backup strategies
* Implement monitoring and alerting
* Review security best practices
# Integration Execution Plane
Source: https://docs.casebender.com/en/deployment/integration-execution-plane
Deploy and operate the credential control plane and dedicated connector workers.
## Required services
Integration workflows require both background services:
* `workflow-processor` owns durable workflow state and publishes connector jobs.
* `connector-worker` is the only consumer of outbound connector jobs and
publishes results back to the workflow processor.
Both services must use the same PostgreSQL database, Redis instance,
`CONNECTOR_ACTION_QUEUE_NAME`, and `CONNECTOR_ACTION_RESULT_QUEUE_NAME`.
Deploy at least one connector worker. It must be always-on; CPU throttling or
scale-to-zero prevents queue consumption.
## Container image
Official releases publish a separate signed
`casebender/connector-worker:` image with SBOM and provenance
attestations. The on-premises Compose bundle starts it automatically. Mirror the
exact release-manifest digest for air-gapped deployments.
## Required secrets
Configure these values in the deployment secret manager:
* `CREDENTIAL_ENCRYPTION_KEY` — at least 32 random characters
* `FIELD_ENCRYPTION_KEY` — at least 32 random characters
* `WEBHOOK_KEY_PEPPER` — at least 32 random characters
* `CONNECTOR_BUNDLE_SIGNING_KEY` — at least 32 random characters
* `OAUTH_BROKER_SECRET` — at least 32 random characters
* `POSTGRES_PRISMA_URL`
* `REDIS_URL`
Keep these keys stable across rolling deployments. Losing the credential
encryption key makes existing credential versions unreadable. Rotating it
requires an explicit re-encryption procedure.
Bind `CREDENTIAL_ENCRYPTION_KEY` (and the `FIELD_ENCRYPTION_KEY` fallback) to
both `connector-worker` and `misp-processor`. The connector worker resolves
credentials for on-demand actions; the MISP processor also hosts scheduled
pull ingestion for Defender, Splunk, CrowdStrike, and the other polling
connectors. The web application alone is not sufficient for polling.
Set `CASEBENDER_PRIVATE_EGRESS_ALLOWLIST` to a comma-separated list only when
workers must reach approved private or on-prem endpoints. Private destinations
remain blocked when the value is empty.
Set `OAUTH_BROKER_BASE_URL` only when an external managed broker is deployed.
Leave it empty for direct vendor OAuth.
## Google Cloud Run
The repository's Google Cloud deployment creates
`casebender-connector-worker` as a private Cloud Run service with:
* Minimum one instance
* CPU always allocated
* Private VPC access to Cloud SQL and Redis
* No unauthenticated ingress
* Port `3015` for liveness and readiness checks
Run `deploy/gcloud/setup-infrastructure.sh` to create the integration secrets,
then deploy all services with `deploy/gcloud/deploy.sh fast`. To deploy only the
worker, run:
```bash theme={null}
deploy/gcloud/deploy.sh connector-worker
```
## Kubernetes
The base Kustomize configuration includes `connector-worker-deployment.yaml`.
The enterprise overlay permits DNS, PostgreSQL, Redis, and HTTPS egress.
Application-level connector and credential host allowlists provide the
destination policy within that network boundary.
## Health checks
* `/health/live` confirms the process is running.
* `/health/ready` confirms the worker is accepting work.
* `/health` returns queue names, active concurrency, and local circuit state.
Alert when no connector-worker instance is ready, the action queue grows
continuously, result delivery fails, or circuits remain open.
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.
# Deploy to OpenShift
Source: https://docs.casebender.com/en/deployment/openshift
Deploy CaseBender on Red Hat OpenShift 4.x with the restricted-v2 overlay
This page is the CaseBender OpenShift installation profile. It is **not** a Red
Hat certification, OperatorHub listing, or production-certified procedure for
every OpenShift minor release. Record the exact OpenShift, CNI, CSI, and
registry versions with your validation output. Use the
[supported on-premises Compose guide](/en/quickstart) when you are not running
on OpenShift.
Object storage on OpenShift Data Foundation (ODF) or Ceph RGW is documented
separately: [OpenShift ODF and Ceph RGW Storage](/en/deployment/storage-openshift-odf-rgw).
Follow that page only after this overlay is customized, or use the composed
`k8s/overlays/openshift-odf-rgw` profile instead of local `/data` PVC storage.
## Overview
This guide deploys CaseBender on **OpenShift 4.x** using the Kustomize overlay
in `k8s/overlays/openshift`. The overlay is built from `k8s/base` and is
designed for the platform **`restricted-v2` SCC**:
* arbitrary non-root UIDs (no fixed `runAsUser`)
* no privilege escalation; all capabilities dropped
* `RuntimeDefault` seccomp
* read-only root filesystems
* no custom SCC (`anyuid`, privileged, or host access)
Do **not** apply `k8s/base` directly on OpenShift. Ingress is replaced by
**Routes**, placeholder Secrets are stripped from the render, and each
container gets an `emptyDir` at `/tmp`.
```
SIEM / analysts
│ HTTPS
▼
OpenShift Route (edge TLS) ──► web, /api/v1, /api/v1/ingest
│
├── webapp, api, ingestion
├── worker, workflow-processor, connector-worker
├── misp-processor, search-sync
└── external PostgreSQL + Redis (+ object storage or RWX PVC)
```
## Prerequisites
1. An OpenShift 4.x cluster with `NetworkPolicy` enforcement (OpenShift SDN or
OVN-Kubernetes).
2. `oc` (and `kubectl` with Kustomize, or `oc kustomize`).
3. Cluster-admin (or equivalent) to prepare the namespace, quotas, registry
trust, and Routes.
4. **External** PostgreSQL 14+ with TLS, and a Redis-compatible queue with TLS.
This overlay does not operate the database or Redis lifecycle.
5. DNS for the Route host and TLS terminated at the OpenShift router (edge).
6. Signed, digest-pinned CaseBender images (and SBOMs) in a registry the
cluster can pull. Production overlays must use **digests**, not floating
tags.
7. A secrets mechanism (External Secrets Operator, sealed secrets, or an
approved injector). The rendered overlay contains **no** Secret objects.
Optional: a connected transfer host if the cluster is disconnected.
## What the overlay deploys
| Workload | Role |
| -------------------- | ------------------------------------------------------- |
| `webapp` | Next.js UI, tRPC, Pub/Sub push URL, attachment routes |
| `api` | REST `/api/v1` |
| `ingestion` | Connector ingest `/api/v1/ingest` |
| `worker` | Queues, storage mutation, checklist reconciliation, SLA |
| `workflow-processor` | Workflow engine |
| `connector-worker` | Private outbound connector actions |
| `misp-processor` | MISP sync (scale-to-zero friendly) |
| `search-sync` | Search index (singleton by default) |
Platform objects: namespace `casebender`, Routes, NetworkPolicies, ResourceQuota,
LimitRange, PodDisruptionBudgets, and (default profile) an RWX PVC `casebender-data`
mounted at `/data` on web.
See [Integration Execution Plane](/en/deployment/integration-execution-plane)
for connector-worker secrets and queue names.
## Step 1: Install the OpenShift CLI
```bash macOS theme={null}
brew install openshift-cli
oc login --server=https://api.cluster.example.com:6443
oc whoami
```
```bash Linux theme={null}
# Follow Red Hat's current OpenShift CLI install for your version:
# https://docs.redhat.com/en/documentation/openshift_container_platform
oc login --server=https://api.cluster.example.com:6443
oc whoami
```
```powershell Windows theme={null}
# Install the oc binary from the OpenShift web console (Command Line Tools)
# or from Red Hat's CLI package for your cluster version.
oc login --server=https://api.cluster.example.com:6443
oc whoami
```
Confirm Kustomize:
```bash theme={null}
kubectl kustomize --help
# or
oc kustomize --help
```
## Step 2: Prepare the cluster
### Namespace and SCC
The overlay creates namespace `casebender`. Workloads must run as
`restricted-v2` with an **arbitrary** UID:
```bash theme={null}
oc -n casebender auth can-i use scc/restricted-v2 \
--as=system:serviceaccount:casebender:default
```
Do not grant `anyuid` or a custom SCC to make a fixed UID work. Images must
run as an arbitrary UID, keep writable paths group `0` / `g=u`, listen on an
unprivileged port, and write only to `/tmp` or `/data`.
### Storage choice
Pick **one**:
| Profile | Overlay | When to use |
| -------------- | -------------------------------- | ---------------------------------------------------------------- |
| Local volume | `k8s/overlays/openshift` | Single-writer or RWX CSI that allows arbitrary UIDs; `/data` PVC |
| ODF / Ceph RGW | `k8s/overlays/openshift-odf-rgw` | Customer-managed ODF; three existing buckets; no `/data` PVC |
The default overlay sets `STORAGE_PROVIDER=local` and `STORAGE_PATH=/data`.
The PVC StorageClass **must** support `ReadWriteMany` if you run more than one
web replica. If it does not, use object storage and the ODF overlay.
CaseBender never creates buckets. ODF/RGW steps:
[OpenShift ODF and Ceph RGW Storage](/en/deployment/storage-openshift-odf-rgw).
### ClamAV
Production user uploads stay quarantined until an external **clamd** scan.
Compose bundles ClamAV; OpenShift does not. Provide `CLAMD_HOST` / TLS or
`CLAMD_SOCKET_PATH` (sidecar). If the scanner is missing, attachments return
HTTP 409 until scan/promotion succeeds.
### Network
Replace bootstrap `0.0.0.0/0` CIDRs in `k8s/overlays/openshift/network-policy.yaml`
with approved ranges for PostgreSQL, Redis, registry, identity, storage, and
connectors **before** production. The ODF overlay additionally restricts RGW
egress; do not restore wildcard egress.
## Step 3: Customize the overlay
Copy `k8s/overlays/openshift` (or `openshift-odf-rgw`) into an
**environment-specific** directory. Do not commit customer hostnames or
secrets into the product repository.
1. **Images** — in `kustomization.yaml`, replace every
`registry.example.com/casebender/...` and `replace-with-release` with the
mirrored **digest**.
2. **Route host** — in `route.yaml`, set `spec.host` on all Routes to the
approved DNS name (default placeholder `casebender.apps.example.com`).
Paths: `/` (web), `/api/v1` (API), `/api/v1/ingest` and `/api/ingest`
(ingestion), `/api/openapi.json` and `/docs` (API docs).
3. **PVC** (local storage profile) — in `platform-controls.yaml`, set
`storageClassName` and size.
4. **ConfigMap** — non-secret settings (`casebender-config`): public URL,
storage provider, feature flags. TLS endpoints only in production.
5. **NetworkPolicy** — approved CIDRs only.
## Step 4: Provision secrets
The overlay **deletes** the base placeholder Secret from the render. Create
`casebender-secrets` in namespace `casebender` **before** the first rollout.
`k8s/overlays/openshift/external-resources.example.yaml` is an External Secrets
example (excluded from Kustomize). Adapt it to your SecretStore. Typical keys:
* `POSTGRES_PRISMA_URL`
* `REDIS_URL`
* `AUDIT_INTEGRITY_SECRET`
* `FIELD_ENCRYPTION_KEY`
* `CREDENTIAL_ENCRYPTION_KEY`
* `WEBHOOK_KEY_PEPPER`
* `CONNECTOR_BUNDLE_SIGNING_KEY`
* `OAUTH_BROKER_SECRET`
Preserve `AUDIT_INTEGRITY_SECRET` across upgrades. Rotating it invalidates the
audit chain. Never put secret values in ConfigMaps, Kustomize patches, or git.
Confirm the Secret exists and the render has no Secret objects:
```bash theme={null}
oc -n casebender get secret casebender-secrets
kubectl kustomize k8s/overlays/openshift | grep -c '^kind: Secret' || true
```
## Step 5: Render, validate, and apply
From the repository root (or your copied overlay tree):
```bash theme={null}
kubectl kustomize k8s/overlays/openshift \
> /tmp/casebender-openshift.yaml
./scripts/openshift/validate.sh /tmp/casebender-openshift.yaml
oc apply --server-side --dry-run=server \
-f /tmp/casebender-openshift.yaml
oc apply --server-side \
-f /tmp/casebender-openshift.yaml
oc -n casebender rollout status deployment --timeout=10m
```
For ODF/RGW storage, render `k8s/overlays/openshift-odf-rgw` instead (it
composes the OpenShift overlay). Provision ObjectBucketClaims **before**
application startup. The adapter never creates buckets.
Web runs database migrations on startup. You do not run Prisma by hand.
## Step 6: Verify
```bash theme={null}
oc -n casebender get pods,route,networkpolicy,pdb,pvc
oc -n casebender logs deploy/webapp --tail=100
oc adm policy scc-subject-review -f /tmp/casebender-openshift.yaml
```
Then confirm:
* every pod has a non-zero arbitrary UID and `restricted-v2`
* writes to the root filesystem fail; `/tmp` (and `/data` if used) succeed
* Routes serve HTTPS only; HTTP redirects
* default-deny NetworkPolicy blocks unapproved traffic
* `/api/health/live` and `/api/health/ready` behave as documented in
[Storage Health and Troubleshooting](/en/deployment/storage-health-troubleshooting)
* a test upload is SHA-256 verified and, with clamd, leaves quarantine
Archive the rendered manifest, image digests, `validate.sh` output, and SCC
review with the change record. Cluster execution is required before calling a
release “OpenShift validated.”
## Disconnected registry
1. On a connected host, download images, checksums, signatures, and SBOMs.
2. Verify, then scan the mirrored digest under your policy.
3. `oc image mirror` (or the approved tool) **by digest**.
4. Configure `ImageDigestMirrorSet` / `ImageTagMirrorSet` if required; wait for
MachineConfigPool convergence.
5. Create a namespace pull secret and link it for pull. Do not commit it.
```bash theme={null}
oc -n casebender create secret docker-registry casebender-registry \
--docker-server=registry.internal.example.com \
--docker-username="$REGISTRY_USER" \
--docker-password="$REGISTRY_PASSWORD"
oc -n casebender secrets link default casebender-registry --for=pull
```
Re-render and confirm every image is the mirror digest. Do not fall back to a
public registry.
## Proxy and custom CA
Cluster-wide proxy is a cluster-admin change (`oc edit proxy/cluster`). If
workloads need `HTTPS_PROXY` / `HTTP_PROXY` / `NO_PROXY`, include cluster
domains, service and pod CIDRs, PostgreSQL, Redis, and storage. Add an egress
rule for the proxy CIDR and port; the bootstrap policy does not open common
proxy ports.
For an internal CA, mount only the CA file (do not replace the image trust
store):
```bash theme={null}
oc -n casebender create configmap casebender-custom-ca \
--from-file=ca-bundle.crt=organization-ca.pem \
--dry-run=client -o yaml | oc apply -f -
```
Mount read-only at
`/etc/pki/ca-trust/source/anchors/casebender-ca.crt` (`subPath`) and set
`NODE_EXTRA_CA_CERTS` to that path. Restart and test TLS to PostgreSQL, Redis,
storage, OIDC, and connectors. Never disable TLS verification as a CA
workaround.
## Backup, upgrade, and rollback
Back up a consistency set: PostgreSQL, object storage (or `/data` snapshot),
secret **versions** (not plaintext in the archive), rendered manifest, and
Route/NetworkPolicy. See
[Storage Backup and Restore](/en/deployment/storage-backup-restore).
Before upgrade, save live objects and the target render:
```bash theme={null}
oc -n casebender get all,pvc,networkpolicy,pdb,resourcequota -o yaml \
> casebender-pre-upgrade.yaml
kubectl kustomize k8s/overlays/openshift > casebender-target.yaml
```
Roll stateless workers before externally exposed services. Application rollback
is allowed only while the database and object format stay backward compatible.
If a non-reversible migration ran, restore; do not point old images at a new
schema.
## Troubleshooting
1. **Pods crash with permission denied / SCC**\
Confirm `restricted-v2`, no fixed UID, group-writable image paths, and
`/tmp` emptyDir.
2. **Route 503 / no backends**\
Check probes, Service port (`webapp` often 80 → container), and rollout.
3. **Attachments HTTP 409 / “Image unavailable”**\
Worker malware scanner not reachable, or storage mutation not running.
Restore clamd; objects stay quarantined until a clean verdict.
4. **Readiness 503 / storage**\
Local PVC vs ODF mismatch, missing buckets, or TLS/CA. Use
[Storage Health](/en/deployment/storage-health-troubleshooting).
5. **Audit errors after upgrade**\
`AUDIT_INTEGRITY_SECRET` changed. Restore the previous value.
## Related documentation
* Overlay runbook in the repository: `k8s/overlays/openshift/README.md`
* [OpenShift ODF and Ceph RGW Storage](/en/deployment/storage-openshift-odf-rgw)
* [Storage Overview](/en/deployment/storage-overview)
* [Upgrading](/en/deployment/upgrading)
* [Integration Execution Plane](/en/deployment/integration-execution-plane)
# Deployment Overview
Source: https://docs.casebender.com/en/deployment/overview
Choose a supported CaseBender deployment path
## Deployment Options
The supported production deployment is an on-premises Docker Compose
installation using the versioned release bundle. The Desktop Installer is a
supported convenience path for local or small installations and uses the same
one-time activation model.
Version-pinned Docker Compose deployment with preflight and local activation
Graphical deployment with generated installation secrets
## Enterprise object storage
Production requires pre-created customer-owned external storage. CaseBender
never creates a bucket/container at runtime and does not embed MinIO.
Provider status, security, backup, migration, and operations guidance
Configure external managed OBC or standalone RGW storage
## Cloud reference architectures
The cloud pages below are reference architectures, not production-certified
installation procedures. Some examples predate the current activation,
secret-management, image-pinning, and network-isolation baseline. Do not use
them for production without an architecture and security review.
Red Hat OpenShift 4.x with restricted-v2, Routes, and optional ODF storage
Serverless container platform with automatic scaling
Deploy on Amazon's cloud infrastructure
Microsoft's cloud platform with enterprise features
Simple and cost-effective cloud platform
## Deployment Considerations
Before deploying CaseBender to production, consider the following:
### Infrastructure Requirements
* **CPU/Memory**: Minimum 2 vCPUs and 8 GB RAM (16 GB recommended for the
full Compose stack with local storage and ClamAV)
* **Storage**: At least 20GB for the application and databases
* **Network**: HTTPS required, with valid SSL certificate
* **Database**: PostgreSQL 14+ instance
* **Cache**: Redis 6+ instance
### Security Considerations
1. **SSL/TLS Configuration**
* Always use HTTPS in production
* Keep certificates up to date
* Configure secure SSL parameters
2. **Network Security**
* Set up proper firewalls
* Use private networking where possible
* Implement rate limiting
3. **Access Control**
* Use strong authentication
* Implement role-based access control
* Regular security audits
### Monitoring and Maintenance
1. **Health Checks**
* Set up application monitoring
* Configure automated health checks
* Implement logging and alerting
2. **Backup Strategy**
* Regular database backups
* Automated backup testing
* Disaster recovery plan
3. **Updates and Maintenance**
* Regular security updates
* Scheduled maintenance windows
* Version control strategy
## Deployment Checklist
Before deploying to any platform, ensure you have:
* [ ] Production-ready SSL certificates
* [ ] Secure environment variables
* [ ] Database backup strategy
* [ ] Monitoring tools configured
* [ ] Security measures implemented
* [ ] Documentation for maintenance procedures
## Next Steps
Choose your preferred deployment platform from the options above to get detailed, platform-specific deployment instructions.
# Permission Visibility Rollout
Source: https://docs.casebender.com/en/deployment/permission-visibility-rollout
Stage permission-driven UI visibility without weakening authorization.
## Security boundary
This rollout controls only whether internal users see navigation and global
actions that their effective permissions do not allow. Direct-route guards,
tRPC procedures, REST routes, service-layer tenant and entity checks, and
external collaborator containment remain permission enforced in every stage.
Never use the visibility rollout state to authorize a read or write. A UI
rollback intentionally restores legacy controls, which can still produce a
server-side denial.
Case-scoped and external collaborators always receive enforced visibility.
Neither the platform stage nor an organization rollback can restore internal
navigation, tenant switchers, notifications, global actions, or search to those
principals.
## Controls
Set these values on every web node and restart or roll the nodes:
```bash theme={null}
# enforce (product default), canary, or observe
PERMISSION_VISIBILITY_ROLLOUT_STAGE=enforce
# Exact organization IDs; used only when the stage is canary
PERMISSION_VISIBILITY_CANARY_ORGANIZATION_IDS=org-pilot-1,org-pilot-2
# Emergency UI-only rollback exceptions in canary or enforce
PERMISSION_VISIBILITY_ROLLBACK_ORGANIZATION_IDS=
```
An unset stage defaults to `enforce`. An invalid explicit stage fails closed to
`enforce`. Empty or malformed list entries are ignored. The controls contain
organization IDs, so manage them as deployment configuration and do not expose
them to browser telemetry.
## Stages
1. **Broad enforcement (default):** Permission-driven hiding applies to every
internal organization except an explicit UI rollback organization.
2. **Canary enforcement:** Set the stage to `canary` and list opted-in
organization IDs. Permission-driven hiding applies only to those
organizations. Other internal organizations remain in observation mode.
3. **Observe/audit:** Internal users retain legacy visibility. Permission route
containment remains active. A visit to a visible but unauthorized route
emits a `hidden_route_mismatch` signal and renders Access Denied.
Promote the same configuration to all web nodes. Mixed stages make telemetry
ambiguous and can cause navigation to change between requests.
## Telemetry and privacy
The authenticated, CSRF-protected telemetry endpoint re-resolves the principal
and rollout before recording a signal. It accepts only an event type and a
capability from the static manifest. It discards spoofed allowed-capability or
wrong-stage signals.
Monitor these OpenTelemetry counters and corresponding structured warning logs:
* `permission_visibility.hidden_route_mismatch`: an observation-stage control
was visible but the permanent route guard denied it;
* `permission_visibility.authorization_denial`: an enforced or external
principal reached a route that its permissions deny.
Labels are limited to rollout stage, enforcement state, rollout reason,
manifest capability, and internal/external principal class. User IDs,
organization IDs, route paths, entity IDs, query strings, tokens, and content
are not accepted or emitted.
## Promotion gates
Before each stage transition:
1. Run the authorization manifest, rollout, telemetry-route, external
collaborator, and sensitive-entrypoint policy tests.
2. Verify a no-permission internal user can see a legacy control in `observe`
but receives Access Denied and a server-side denial from direct API calls.
3. Verify a canary organization hides the same control while a non-canary
organization does not.
4. Verify external collaborators see only the case-scoped shell in every stage.
5. Review mismatch and denial rates by capability. Investigate unexpected
increases or a capability that has no expected authorized role.
6. Keep a stage through one deployment cycle, one permission-cache TTL, and one
fresh-login cycle before expanding.
## UI-only rollback
For one organization, add its exact ID to
`PERMISSION_VISIBILITY_ROLLBACK_ORGANIZATION_IDS`. For a platform rollback, set
`PERMISSION_VISIBILITY_ROLLOUT_STAGE=observe`. Roll all web nodes and verify the
resolved `reason` label is `organization-rollback` or `platform-observe`.
Do not revert authorization middleware, permission requirements, tenant/entity
scope checks, route guards, or external collaborator restrictions. Do not
interpret restored controls as restored access. Remove the rollback exception
after the denial or role-template issue is understood and corrected.
## Operator follow-up
Operators must supply real canary organization IDs, configure collection and
alerts for the two counters, choose acceptable mismatch/denial thresholds,
record Security and Product approval for each promotion, and rehearse the
UI-only rollback in staging. Preserve rollout logs through the post-release
review window.
# Backup and Recovery
Source: https://docs.casebender.com/en/deployment/recovery
Back up, restore, and recover an on-premises CaseBender installation
Recovery must preserve tenant data, audit records, encryption material,
activation state, and the credentials needed to read existing data.
## Back up
Back up all of the following as one recovery set:
* PostgreSQL, including deployment and audit tables;
* every referenced external-storage object at its exact provider
version/generation, with size and SHA-256;
* the `casebender_secret` volume or externally managed license secret;
* `.env`, externally managed encryption keys, and the exact
`AUDIT_INTEGRITY_SECRET` used by the restored audit database;
* custom TLS trust and integration configuration; and
* the exact pinned image manifest and Compose release.
Legacy `app`/`db` installations may store attachments in `miniodata` and the
license key in `casebender_secret`, while the signed bundle stores local files
in `casebender_data` only for historical/single-node layouts and the license key
in `.env`. New production installations require external storage. Back up the
legacy source layout before changing it. See
[Migrate a Legacy Docker Compose Installation](/en/deployment/legacy-compose-migration).
Encrypt recovery sets, restrict access, store a copy outside the Docker host,
and record a checksum.
Example PostgreSQL backup:
```bash theme={null}
docker compose -f docker-compose.prod.yml exec -T postgres \
sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' \
> casebender-$(date +%F).sql
```
Do not include plaintext secrets in backup logs or ticket attachments.
Restoring or rotating `AUDIT_INTEGRITY_SECRET` independently of PostgreSQL
breaks verification of existing chained audit records.
Create the database-linked object manifest and test an isolated exact-version
restore with `scripts/storage/verify-backup-restore.ts`. Follow
[Storage Backup and Restore](/en/deployment/storage-backup-restore); a database
dump and an eventually consistent bucket copy taken at unrelated times are not
a valid recovery point.
## Restore rehearsal
At least quarterly:
1. provision an isolated recovery network;
2. restore the database, object storage, `.env`, and encryption material;
3. start the same pinned CaseBender version;
4. run `./casebender preflight`;
5. verify users, organizations, cases, attachments, API-key status, and audit
chain integrity;
6. record actual recovery point and recovery time.
Never connect a recovery rehearsal to production integrations.
## Lost administrator access
Do not delete deployment state, rerun production seeding, or enable shared
default credentials. Use another authorized super administrator or the
documented identity-provider recovery flow.
If no administrator remains, restore through the approved break-glass procedure
with two-person authorization and preserve an immutable audit record. Contact
CaseBender support for the version-specific recovery command.
## Lost activation code
For a new installation that is still activation-pending:
```bash theme={null}
./casebender activation-code
```
The replacement invalidates the previous code. This command cannot reset an
active installation or change an existing administrator.
## Rollback after an upgrade
Follow the target release's migration compatibility notes. Do not run an older
application against a newer unsupported schema. Restore the pre-upgrade
database and matching volumes, then start the previous pinned image set.
For releases explicitly documented as backward schema-compatible, use:
```bash theme={null}
./casebender rollback --confirm-schema-compatible
```
This restores only the previous immutable image pin. It does not reverse or
restore database migrations.
See [Upgrading CaseBender](/en/deployment/upgrading) for the complete sequence.
# Deployment Security
Source: https://docs.casebender.com/en/deployment/security-hardening
Required security controls for production and air-gapped CaseBender deployments
Use this checklist with the complete
[Hardening Guide](/en/security/hardening-guide).
## Release gate
* Deploy a signed, pinned release; never use `latest`.
* Run `./casebender preflight`.
* Publish only Nginx ports 80 and 443.
* Use trusted TLS and redirect HTTP to HTTPS.
* Keep PostgreSQL, Redis, OpenSearch, API, ingestion, and processors on
internal networks. Permit web and worker to reach only the approved external
object-storage and malware-scanner endpoints.
* Store `.env`, encryption keys, and license material in an approved secret
store with least-privilege access.
* Require the same `AUDIT_INTEGRITY_SECRET` on every `web`, `api`, and `worker`
process that writes chained audit records.
* Preserve `AUDIT_INTEGRITY_SECRET` with the database recovery set across
upgrades and restores. Rotating or losing it prevents verification of the
existing audit chain.
* Complete one-time activation and MFA enrollment.
* Configure exact-host HTTPS egress allowlists only where needed.
* Centralize redacted security and audit logs.
* Verify encrypted backups and a tested restore.
* Apply the [Storage Security Baseline](/en/deployment/storage-security-baseline);
production bundles do not embed MinIO.
## Before promotion
```bash theme={null}
pnpm security:policy
pnpm security:test
node scripts/deployment/preflight.mjs --configuration-only
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
A general-availability release also requires a fresh Codex Security scan. Use
`pnpm security:compare ` to block new critical or high
findings and reconcile every baseline fingerprint.
## Air-gapped deployment
Import container images, signatures, checksums, and the SBOM through the
organization's approved transfer process. Mirror them in a trusted internal
registry and preserve the original digest. Browser activation remains local and
does not require outbound internet access.
# Security Remediation Release
Source: https://docs.casebender.com/en/deployment/security-remediation-release
Upgrade impact and operator actions for the enterprise security remediation release
This release introduces server-derived authorization, scoped tenant and TLP
queries, one-time local activation, delegated API-key permissions, hardened
egress, bounded ingestion and queue messages, temporary login lockouts, and
production deployment preflight.
## Existing installation impact
Existing databases with users are migrated to `ACTIVE`. Existing passwords,
users, roles, organizations, cases, API keys, and attachments are preserved. No
new administrator is seeded and the setup wizard is not shown.
## Operator actions
1. Back up PostgreSQL, attachments, `.env`, encryption material, and license
state.
2. Test the upgrade with a sanitized copy of the client database.
3. Add strong Redis and OpenSearch credentials. If an older deployment embeds
MinIO, preserve it as a read-only migration/rollback source and follow
[MinIO Lifecycle](/en/deployment/storage-minio-lifecycle); do not configure
MinIO as a new production provider.
4. Apply the signed bundle with `./casebender upgrade --version 1.0.9` or, on
an air-gapped host,
`./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz`. The
command preserves an existing `AUDIT_INTEGRITY_SECRET` or creates one
installation-specific value before preflight. If an older bundle must be
remediated manually, set the value only when it is absent:
```bash theme={null}
if ! grep -q '^AUDIT_INTEGRITY_SECRET=.' .env; then
printf 'AUDIT_INTEGRITY_SECRET=%s\n' "$(openssl rand -hex 32)" >> .env
fi
```
Do not append a duplicate key. Store the value with the backup set and do not
rotate it during routine upgrades.
Audit entries created before this release remain marked as legacy,
unchained records. Integrity verification reports their count separately;
every entry created after the upgrade must belong to the HMAC chain.
5. Replace mutable image tags with the release's pinned tags or digests.
6. Publish only Nginx ports and install trusted TLS files.
7. Run preflight and the post-deployment canary.
8. Review integration URLs. Private HTTPS destinations require an exact-host
`CASEBENDER_PRIVATE_EGRESS_ALLOWLIST` entry.
## Compatibility controls
`CASEBENDER_LEGACY_BOOTSTRAP` remains disabled by default. It requires
`ACCEPT_LEGACY_BOOTSTRAP_RISK=true`, an approved owner and expiry, and must not
be enabled for a new production installation.
## Release evidence
* `scripts/security/codex-findings-map.json` maps all 510 baseline fingerprints.
* `pnpm security:policy` enforces repository invariants.
* `pnpm security:test` runs tenant, TLP, SSRF, regex, and queue abuse cases.
* `scripts/security/security-remediation-release.json` defines staged promotion
and rollback criteria.
A fresh independent scan is required before general availability; implementation
status alone is not evidence that a finding disappeared from scanner output.
# Storage Backup and Restore
Source: https://docs.casebender.com/en/deployment/storage-backup-restore
Protect PostgreSQL and exact object versions as one consistency set
A CaseBender recovery point is PostgreSQL plus every referenced exact object
version, configuration, and cryptographic key. A database dump or bucket copy
alone is not a valid recovery set.
## Recovery-set contents
* a PostgreSQL snapshot/dump and migration identifier;
* every non-deleted finalized `StoredObject` at its recorded `profileKey`,
`objectKey`, and `providerVersion`;
* SHA-256 and size for each object;
* backup profile, backup object key, and exact backup version;
* storage/identity/CA configuration versions;
* field, credential, audit-integrity, authentication, and signing keys;
* immutable CaseBender image digests and release manifest; and
* timestamp, approvals, tool versions, measured RPO/RTO, and evidence digest.
Encrypt the set, restrict access, and store it independently of the primary
failure domain. Do not write credentials or object contents to backup logs.
## Capture a consistency point
Quiesce user/integration writes or use a provider/database snapshot method that
guarantees an equivalent consistency boundary. Drain or durably pause workers.
Record the PostgreSQL snapshot/LSN and exact object versions before resuming.
Generate the object inventory:
```bash theme={null}
pnpm storage:backup-verify inventory \
--output ''
chmod 600 ''
```
The command runs a serializable database transaction and refuses objects
without exact version, SHA-256, or size metadata. It does not copy the bytes;
the approved backup process must populate `backupProfileKey`,
`backupObjectKey`, and `backupVersionId` for every manifest entry.
Hash and protect the completed manifest:
```bash theme={null}
sha256sum '' \
> '.sha256'
```
## Copy policy
Copy first and retain the primary. Never use a destructive synchronization
operation as the first backup or migration step. Verify bytes by downloading
and calculating SHA-256; do not rely on ETags.
Preserve all required historical versions and retention/hold state. Ordinary
object copy may not preserve provider-specific ACL, CMEK, Object Lock,
immutability, legal hold, event-based hold, metadata, or version history.
Attest and reproduce those controls at the destination.
## Isolated restore verification
Restore PostgreSQL to an isolated environment using the same compatible
CaseBender release. Ensure the manifest's database migration and stored-object
metadata match, then restore objects to a dedicated verification prefix:
```bash theme={null}
pnpm storage:backup-verify verify-restore \
--manifest '' \
--target-profile '' \
--isolated-prefix 'tenants//restore-verification/' \
--evidence-output ''
```
The script reads each exact backup version, verifies size and SHA-256, uploads
to the isolated target, downloads it, and verifies SHA-256 again. It writes the
evidence file with mode `0600`. Clean up the isolated prefix through the
approved retention-aware process after evidence review.
Then verify login, organizations, cases, evidence, attachments, exports,
scanner state, retention, legal hold, audit-chain integrity, and authorization.
Never connect a rehearsal to production integrations.
## Provider caveats
### S3 and Ceph RGW
Capture version IDs and all delete markers. Object Lock must exist when the
bucket is created and cannot be inferred from an adapter. A copied object may
receive a new version and retention state. Use the exact certified product
version and private CA during restore.
### Google Cloud Storage
Capture numeric generations. Validate retention-policy lock, object retention,
event-based holds, CMEK access, uniform bucket access, and public-access
prevention. Generation numbers change when copied to another bucket.
### Azure Blob Storage
Capture blob version IDs. Validate secure transfer, account/container
versioning, encryption keys, immutability policy, and legal holds. Restored
versions receive destination-specific IDs.
### Local or legacy MinIO
Local storage is not a production target. Preserve both legacy MinIO volume
snapshots and API-level exact-object exports during migration; never import
MinIO's internal layout as ordinary files.
## RPO and RTO evidence
Record:
* last included database transaction and object version;
* first excluded transaction;
* backup duration, restore duration, validation duration, and service resume
time;
* actual data-loss interval (RPO) and recovery duration (RTO);
* missing, changed, unreadable, held, or policy-blocked objects; and
* rollback exercise outcome.
A policy target is not evidence. Retain measured results for every supported
release train and after material storage changes.
See [Storage Migration](/en/deployment/storage-migration-runbook) for cutover
and rollback and [Backup and Recovery](/en/deployment/recovery) for the wider
installation recovery set.
# Storage Health and Troubleshooting
Source: https://docs.casebender.com/en/deployment/storage-health-troubleshooting
Diagnose readiness, scanner, CA, permission, canary, and dead-letter failures
Use health responses for routing and sanitized triage. Use protected logs,
metrics, provider audit records, and database state for diagnosis.
## Web health endpoints
| Endpoint | Meaning | Success | Failure |
| ------------------- | ----------------------------------------------------------- | ---------------------- | --------------------------------------------------- |
| `/api/health/live` | Web process is running; no external checks | `200 {"status":"ok"}` | Process/network failure |
| `/api/health/ready` | Storage profiles are reachable and the deep canary is fresh | `200`, `status: ready` | `503`, `status: not_ready` and sanitized `category` |
Readiness categories are only `configuration`, `authentication`, `tls`,
`storage`, `capability`, and `canary_stale`. The response intentionally omits
providers, endpoints, bucket names, object keys, credentials, and raw errors.
```bash theme={null}
curl --fail --silent --show-error \
'https:///api/health/live'
curl --fail --silent --show-error \
'https:///api/health/ready'
```
Do not use liveness to decide that writes are safe. Do not put a credential in
a probe URL.
## Deep canary
The scheduled deep canary writes random bytes to `ephemeral`, records SHA-256
metadata, reads and hashes the exact bytes, copies and verifies them, then
deletes both objects. Readiness reports `canary_stale` when no successful
canary exists within the freshness window.
For a stale canary:
1. confirm web instrumentation started the canary scheduler;
2. inspect `storage.readiness`, `storage.operation.*`, and provider latency;
3. confirm `ephemeral` permits conditional create, read, copy, and delete;
4. check worker/web clock and event-loop saturation;
5. verify lifecycle policy is not deleting canary objects during the
transaction; and
6. run the provider contract from the same network and identity context.
Do not permanently lengthen the age threshold to hide failures.
## Category triage
### `configuration`
Validate `STORAGE_CONFIG_FILE` readability/mode and strict JSON; all three
profiles must exist. Use canonical provider IDs `s3`, `gcs`, `azure`, or
`local`. Production cannot use `local`.
### `authentication`
Check workload-identity binding, role scope, token audience, credential
rotation overlap, and provider audit denials. Web and worker need matching
access. Do not print tokens, run `env`, or copy Secret data into a ticket.
### `tls`
Check endpoint DNS/SAN, private CA mount, complete issuing chain, expiry,
proxy trust, and pod restart after CA rotation. Keep verification enabled;
never use HTTP, `--insecure`, or `rejectUnauthorized: false`.
### `storage`
Confirm the existing bucket/container, route, DNS, egress, quota, throttling,
capacity, and required object operations. Health checks do not create missing
storage.
### `capability`
When WORM is required, verify profile `requireWorm`, versioning, object
retention/immutability, and legal hold. Re-run live qualification after policy
changes.
## Scanner outage
Symptoms include increasing `storage.quarantine.depth`,
`storage.quarantine.oldest_age_seconds`, `storage.scanner.failure`, outbox
retries, and eventual dead letters.
Check the `clamd` socket/host, TLS CA, server name, size limit, timeout, network
policy, engine health, and signature update status. Restore the scanner, then
allow normal idempotent retries or use the approved replay procedure. Objects
must remain quarantined until a terminal clean verdict; never mark them clean
manually or bypass scanning.
Cloud Run reference deploys set `MALWARE_SCANNER_PROVIDER=skip` because there
is no ClamAV sidecar. That is an explicit integrity-only exception. If
attachments stay on HTTP 409, confirm the worker started the storage mutation
processor and is not missing that variable.
## Mutation dead letters
Monitor `storage.outbox.deadletter`, `storage.outbox.pending`, and
`storage.outbox.deadlettered`. Inspect protected
`StorageMutationOutbox` records by ID/status/operation without exporting
payloads or object keys unnecessarily.
1. classify scanner, permission, retention, TLS, missing-object, or provider
failure;
2. repair the cause;
3. confirm the object still matches its stored SHA-256 and exact version;
4. replay through the approved idempotent queue operation; and
5. confirm completion and audit evidence.
Never delete a dead-letter row to make a dashboard green. Retention-blocked
deletes are policy failures to resolve, not objects to force-delete.
## Migration and reconciliation
Monitor `storage.migration.result`,
`storage.reconciliation.missing`,
`storage.reconciliation.orphan_observed`,
`storage.reconciliation.orphan_confirmed`, and reconciliation outbox repair
metrics.
* Missing expected objects are moved back to a quarantined/failed-integrity
state.
* Orphans are observed first and confirmed only after the grace period.
* Migration retries can reach `DEAD_LETTER`; keep the source and investigate
before replay.
Do not automatically delete confirmed orphans. Correlate them with upload
sessions, migration ledgers, provider versions, retention, and legal holds.
## Safe validation
Use a dedicated prefix and workload-equivalent identity:
```bash theme={null}
STORAGE_TEST_PROVIDER=s3 \
STORAGE_TEST_BUCKET='' \
AWS_REGION='' \
./scripts/storage/validate-storage.sh
```
For ODF/Ceph, use `./scripts/storage/validate-ceph-rgw.sh` with the exact
version and private CA. Sanitize outputs before attaching them to an incident.
# Local Storage Limitations
Source: https://docs.casebender.com/en/deployment/storage-local
Default Docker-volume storage is single-host; object storage is optional
Local storage writes files to a named Docker volume at `/data`. New installs
use it by default. You can keep it after you apply an enterprise license.
Object storage (S3, GCS, Azure) is optional.
## Default local volume
`./casebender init` with no storage variables, and the Desktop Installer with
no storage fields filled, set `STORAGE_PROVIDER=local`. Files persist on a
named Docker volume mounted at `/data` for both web and worker. A bundled
ClamAV sidecar listens only on the internal Compose network.
The application shows a local-storage banner. To move to S3, GCS, Azure, or
certified S3-compatible storage, follow
[Storage Migration](/en/deployment/storage-migration-runbook).
## Limits
* One host holds both the application and the files. Keep replica count at
one. Losing the volume loses attachments and evidence.
* There is no provider versioning, object lock, legal hold, or cloud audit
control.
* Multiple replicas need an external shared filesystem with separately
qualified consistency. Do not treat a host path as a hidden object store.
* Container-local and anonymous volumes can be lost when a container is
replaced.
* Filesystem permissions and backup consistency are host-specific.
Do not enable MinIO.
## Operating a local volume
* Run web and worker on the same host and path.
* Encrypt the volume and back it up independently of the application.
* Monitor capacity, permissions, checksum failures, and backup restoration.
* Plan migration to S3, GCS, or Azure when you need more than one host or
provider retention controls.
Follow [Storage Migration](/en/deployment/storage-migration-runbook) using
copy-first, non-destructive transfer and SHA-256 verification.
# Storage Migration Runbook
Source: https://docs.casebender.com/en/deployment/storage-migration-runbook
Copy, verify, cut over, and roll back provider storage without data loss
This runbook migrates CaseBender objects without changing object keys. It uses
copy-first semantics: the source remains authoritative and intact until the
rollback window expires. It applies to local filesystems, MinIO/S3-compatible
storage, AWS S3, and GCS through `rclone` remotes.
## Preconditions
* Read the storage support policy and release notes for both providers.
* Confirm the release uses the provider-neutral durable deletion outbox. The
historical MinIO-only deletion gap is fixed; do not carry that stale
limitation into a new design.
* Confirm destination capacity, encryption, versioning, retention, lifecycle,
object-size, metadata, and naming behavior.
* Create least-privilege source-read and destination-write migration identities.
* Configure TLS trust; never use `--no-check-certificate`.
* Take and test a consistency backup of PostgreSQL and source storage.
* Record object count, total bytes, source versions/snapshots, and configuration.
* Set a change window that permits write quiescence and rollback.
Generate and protect the authoritative PostgreSQL object inventory:
```sh theme={null}
pnpm storage:backup-verify inventory \
--output ''
chmod 600 ''
```
Every migrated item must identify an exact source object version/generation,
size, and SHA-256. PostgreSQL and those exact versions are one consistency set.
Do not migrate a floating “latest” object when a version is recorded.
Examples below use `source:casebender` and `destination:casebender`. Keep rclone
configuration and logs outside the repository and protect them as sensitive.
## 1. Inventory and dry run
```sh theme={null}
rclone version
rclone size source:casebender --json > source-size.before.json
rclone lsf source:casebender --recursive --files-only \
> source-objects.before.txt
rclone copy source:casebender destination:casebender \
--checksum --metadata --dry-run --log-level INFO \
--log-file migration-dry-run.log
```
Review unsupported metadata warnings. Provider-specific encryption, retention,
legal hold, ACL, and version history may not copy as ordinary object metadata;
configure those controls at the destination and preserve source versions in the
backup. Never use `sync` for the initial copy because it can delete destination
objects.
## 2. Seed copy while the application is online
```sh theme={null}
rclone copy source:casebender destination:casebender \
--checksum --metadata --fast-list --transfers 8 --checkers 16 \
--log-level INFO --log-file migration-seed.log
```
Tune concurrency below provider throttle limits. Retry failed objects and retain
the complete log. Do not infer integrity from ETags: multipart and encrypted
objects may have non-MD5 ETags.
## 3. Quiesce writes and capture the consistency point
Block user and integration writes using the release's maintenance procedure.
Pause ingestion and workers only after the queue is drained or durably retained.
Record the database timestamp/LSN, source bucket version/snapshot, and deployment
replicas. Verify no storage writes are occurring.
Run the final delta:
```sh theme={null}
rclone copy source:casebender destination:casebender \
--checksum --metadata --fast-list --transfers 8 --checkers 16 \
--log-level INFO --log-file migration-final.log
```
Do not delete or disable the source.
## 4. Verify before cutover
```sh theme={null}
rclone check source:casebender destination:casebender \
--download --one-way --combined migration-check.txt
rclone size source:casebender --json > source-size.final.json
rclone size destination:casebender --json > destination-size.final.json
```
`rclone check --download` hashes downloaded content and avoids provider ETag
ambiguity. Require zero missing, changed, or unreadable objects. Investigate
count differences from provider marker objects or local `.meta.json` sidecars;
do not waive differences without a recorded explanation.
Run the destination contract test from the application network:
```sh theme={null}
STORAGE_TEST_PROVIDER=s3 \
STORAGE_TEST_ENDPOINT=https://storage.example.com \
STORAGE_TEST_BUCKET=casebender \
AWS_REGION=us-east-1 \
./scripts/storage/validate-storage.sh
```
For GCS or local examples, see the script usage. Also sample high-value evidence,
large multipart objects, Unicode names, empty files, MIME metadata, and retained
objects.
## 5. Cut over
1. Save the old provider configuration and Secret resource version in the
encrypted change record.
2. Confirm the `StorageMigrationLedger` entries are `VERIFIED`. The migration
processor copies first, reads back, verifies SHA-256, records the destination
provider version, and only then transitions to `CUTOVER`.
3. Change only the explicit provider profiles and credentials. Preserve bucket
contents and durable keys.
4. Restart the web application and wait for `/api/health/ready`.
5. Run application upload/download/list/copy/delete tests and verify SHA-256.
6. Verify existing attachments and evidence across several ages and sizes.
7. Resume workers and ingestion, then user writes.
8. Monitor storage errors, failed deletes, latency, throttling, queue depth, and
audit events continuously through the rollback window.
Do not run database key rewrites unless a release-specific migration explicitly
requires them.
During a documented compatibility window, legacy references may be read from
the source while ledger-backed objects use the destination. Do not implement
unbounded dual writes. Close legacy reads only after reconciliation confirms
there are no missing references and rollback approval permits it.
## 6. Rollback
Rollback is safe only while the old source is retained and new writes can be
reconciled.
1. Re-enter maintenance mode and quiesce writes.
2. Record all objects written to the destination since cutover.
3. Copy the reverse delta to the source without deletion:
```sh theme={null}
rclone copy destination:casebender source:casebender \
--checksum --metadata --fast-list \
--log-level INFO --log-file rollback-copy.log
rclone check destination:casebender source:casebender \
--download --one-way --combined rollback-check.txt
```
4. Require a clean check, then restore the prior provider configuration and
credential version.
5. Restart, run application lifecycle/integrity tests, and resume traffic.
6. Keep both stores and all evidence until incident/change review completes.
If source retention or policy prevents the reverse copy, stop and restore the
recorded consistency backup; do not improvise destructive synchronization.
## 7. Closeout
* Reconcile final counts/bytes and archive hashes, logs, tool versions, approvals,
configuration versions, and sampled application results.
* Rotate temporary migration credentials.
* Keep source read-only for the approved rollback period.
* After formal sign-off and legal/retention review, remove source data using the
provider's audited disposal process.
* Update the support record with provider product/version, TLS/CA details,
contract result, performance result, backup result, and rollback exercise.
Run an isolated restore verification before source disposal:
```sh theme={null}
pnpm storage:backup-verify verify-restore \
--manifest '' \
--target-profile '' \
--isolated-prefix 'tenants//restore-verification/' \
--evidence-output ''
```
Record actual recovery point and recovery time. RPO/RTO objectives without a
measured restore and rollback exercise are not evidence.
## Provider-specific caveats
* **S3/Ceph RGW:** preserve version IDs and delete markers; ordinary copies may
not retain Object Lock/legal-hold state. Requalify the exact product version
and private CA.
* **GCS:** preserve numeric generations; bucket retention, object retention,
event-based holds, and CMEK policy need separate destination attestation.
* **Azure:** preserve blob version IDs; immutability and legal hold are
destination-specific and copied blobs receive new version IDs.
* **Legacy MinIO:** keep both the original volume snapshot and S3 API export.
Never import MinIO's internal filesystem layout into another provider.
See [Backup and Restore](/en/deployment/storage-backup-restore) and
[MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
# MinIO Lifecycle and Migration
Source: https://docs.casebender.com/en/deployment/storage-minio-lifecycle
CaseBender policy for legacy MinIO Community Edition deployments
MinIO Community Edition entered maintenance/source-only distribution in late
2025 and its upstream community repository was archived in 2026. Existing
servers may continue to run, but upstream community binaries and normal patch
delivery are no longer a dependable production lifecycle.
This upstream status does not create a CaseBender commitment to operate,
patch, redistribute, or support MinIO. Consult MinIO's current official notices
and your supplier contract for authoritative third-party lifecycle terms.
## CaseBender policy
* New production installations cannot select a native `minio` provider.
* Production bundles and installers do not embed a MinIO service, root
credential, volume, or native MinIO SDK.
* CaseBender does not create a new MinIO bucket at runtime.
* Historical database enum values and migration history remain so upgrades do
not destroy or reinterpret existing records.
* A legacy MinIO service may be used only as a read source during an approved
migration window.
* No retirement date or long-term support promise is made beyond the current
implementation. Customer-specific dates belong in an approved change plan.
Do not configure a legacy endpoint as a new generic S3 production backend
without exact-product live certification under the current release matrix.
## Migration window
Define a bounded window with:
* owner and approver;
* last supported source image/version and vulnerability review;
* write-freeze and rollback decision times;
* source retention deadline;
* tested PostgreSQL plus exact-object-version recovery set;
* destination live qualification;
* RPO/RTO targets and measured rehearsal evidence; and
* legal-hold/retention approval before any source disposal.
## Preserve before changing anything
Keep both:
1. a storage-level snapshot/archive of the original `miniodata` layout for
disaster recovery; and
2. an object-level export through the S3 API preserving keys, metadata where
supported, object versions, sizes, and independently calculated SHA-256.
MinIO's internal filesystem layout is not a valid import format for another
provider. Never copy internal volume files directly into local or cloud object
storage.
Back up PostgreSQL at the same consistency point and preserve `.env`,
encryption keys, `AUDIT_INTEGRITY_SECRET`, release image digests, TLS trust, and
source credentials in the approved secret/recovery systems.
## Copy-first migration
Use [Storage Migration](/en/deployment/storage-migration-runbook):
1. inventory PostgreSQL object references and exact source versions;
2. copy without deleting or overwriting the source;
3. verify destination size and downloaded SHA-256;
4. record each item in `StorageMigrationLedger`;
5. quiesce writes and copy the final delta;
6. switch reads only after verification;
7. keep legacy/dual reads available only for the documented compatibility
window; and
8. retain the source read-only until rollback approval expires.
Do not use `sync`, delete the source, rotate away required credentials, or
change object keys during initial copy.
## Rollback
Rollback requires the original source and matching database recovery point.
Quiesce writes, copy destination-only changes back non-destructively, verify
SHA-256, then restore the prior profile configuration. If reverse copy cannot
be proven, restore the complete PostgreSQL-plus-object consistency set.
Never point an older application at a database schema it does not support.
## Validation and closeout
Run destination live qualification, application upload/scan/promote/download/
delete tests, `scripts/storage/verify-backup-restore.ts`, and a rollback
rehearsal. Retain sanitized evidence, ledger status, counts, hashes, RPO/RTO,
approvals, and source-disposal authorization.
# OpenShift ODF and Ceph RGW Storage
Source: https://docs.casebender.com/en/deployment/storage-openshift-odf-rgw
Connect CaseBender to customer-managed OBC or standalone Ceph RGW storage
This page is **storage only**. For the full OpenShift install (Routes, SCC,
secrets, validate, apply), see [Deploy to OpenShift](/en/deployment/openshift).
This profile connects CaseBender to existing customer-managed OpenShift Data
Foundation (ODF) or Ceph RGW. CaseBender is an S3 client; it does not install,
upgrade, back up, monitor, or administer ODF, Ceph, RGW, users, or buckets.
Current live certification is pending customer credentials and exact-version
evidence. The overlay is configured and qualification-ready, not certified.
## Storage layout
Provision three independent external buckets:
| Purpose profile | Required behavior |
| --------------- | --------------------------------------------------------------------------- |
| `quarantine` | Initial user uploads; scanner-only promotion path; no public access |
| `records` | Durable attachments/evidence/exports; versioning and required WORM controls |
| `ephemeral` | Deep canaries and short-lived exports; bounded lifecycle policy |
All three must exist before startup. The runtime adapter never creates a bucket.
The overlay uses HTTPS, path-style S3 addressing, verified private CA trust,
AES-256 server-side encryption requests, and SHA-256 application integrity.
## Option A: external managed OBCs
Identify the customer-approved RGW bucket StorageClass:
```bash theme={null}
oc get storageclass \
-o custom-columns=NAME:.metadata.name,PROVISIONER:.provisioner
oc api-resources | rg -i objectbucketclaim
```
Copy
`k8s/overlays/openshift-odf-rgw/object-bucket-claims.example.yaml`
to the customer environment repository, replace the StorageClass placeholder,
and apply it separately from CaseBender. Bucket lifecycle remains owned by the
storage operator.
```bash theme={null}
oc apply -f ''
oc -n casebender wait --for=jsonpath='{.status.phase}'=Bound \
objectbucketclaim/casebender-quarantine \
objectbucketclaim/casebender-records \
objectbucketclaim/casebender-ephemeral \
--timeout=10m
```
Confirm, without printing values, that each generated ConfigMap provides
`BUCKET_HOST`, `BUCKET_PORT`, `BUCKET_NAME`, and `BUCKET_REGION`, and each
Secret provides `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. If the OBC
operator uses other keys, patch `valueFrom`; never copy credentials into a
ConfigMap or Kustomize file.
## Option B: standalone external RGW
Use
`k8s/overlays/openshift-odf-rgw/standalone-rgw-resources.example.yaml`
as a mapping example. Replace every `.invalid` endpoint and bucket placeholder
in the customer overlay. Use the installed external-secret controller or
another approved secret injector. Keep endpoints and bucket names in
ConfigMaps, credentials in Secrets, and all real values outside this repository.
The restricted init container reads these resources and writes a strict
`STORAGE_CONFIG_FILE` to a memory-backed `emptyDir` with mode `0400`. Web and
worker mount it read-only.
## Private CA
Create a CA ConfigMap containing only the issuing chain:
```bash theme={null}
oc -n casebender create configmap casebender-rgw-ca \
--from-file=ca.crt='' \
--dry-run=client -o yaml | oc apply -f -
```
The certificate must cover the exact RGW hostname. TLS verification remains
enabled. Never use an unlisted IP address, an HTTP endpoint, `--insecure`, or a
certificate-bypass option.
## Egress
The included policy permits web and worker to reach TCP 443 on pods labelled
`app=rook-ceph-rgw` in `openshift-storage`. Verify the actual namespace, labels,
port, and CNI behavior.
For external RGW, copy and adapt
`external-rgw-network-policy.example.yaml` with stable approved CIDRs, or route
through an operator-controlled egress proxy. Kubernetes NetworkPolicy cannot
select FQDNs. Do not restore wildcard `0.0.0.0/0` or `::/0` egress.
Add separate least-privilege policies for PostgreSQL, Redis, identity, scanner,
and approved integrations.
## Scanner prerequisite
Production user uploads require external `clamd`. The provided worker patch
expects `casebender-malware-scanner` (`host`, `port`) and
`casebender-malware-scanner-ca` (`ca.crt`) and enables TLS. A same-pod scanner
may instead use `CLAMD_SOCKET_PATH`. If the scanner is unavailable, objects
remain quarantined and retries can eventually dead-letter; downloads do not
fail open.
## Render and validate
```bash theme={null}
kubectl kustomize k8s/overlays/openshift-odf-rgw \
> /tmp/casebender-openshift-odf-rgw.yaml
./scripts/openshift/validate.sh \
/tmp/casebender-openshift-odf-rgw.yaml
oc apply --server-side --dry-run=server \
-f /tmp/casebender-openshift-odf-rgw.yaml
oc apply --server-side \
-f /tmp/casebender-openshift-odf-rgw.yaml
oc -n casebender rollout status deployment/webapp deployment/worker \
--timeout=10m
```
Then run live qualification from the workload network and trust context:
```bash theme={null}
STORAGE_TEST_ENDPOINT='https://' \
STORAGE_TEST_BUCKET='' \
AWS_REGION='' \
STORAGE_TEST_CA_BUNDLE='' \
STORAGE_TEST_ODF_VERSION='' \
STORAGE_TEST_CEPH_VERSION='' \
STORAGE_TEST_CAP_VERSIONING='' \
STORAGE_TEST_CAP_DELETE_MARKERS='' \
STORAGE_TEST_CAP_OBJECT_LOCK='' \
./scripts/storage/validate-ceph-rgw.sh
```
Supply credentials through the AWS credential chain, scoped to the dedicated
test bucket/prefix. Complete and sign
`apps/docs/en/deployment/odf-ceph-rgw-validation-evidence.md`. A render,
emulator test, or unsigned transcript is not live certification.
## Credential rotation
1. Rotate through the supported ODF/Ceph procedure; do not hand-edit an
operator-owned OBC Secret.
2. Allow a bounded overlap while the generated Secret or ExternalSecret
refreshes.
3. Restart web and worker so the init container regenerates the mounted file.
4. Require `/api/health/ready` and live contract validation to pass.
5. Revoke the old credential and check sanitized authentication metrics/logs.
## CA rotation
1. Publish a temporary CA bundle containing old and new issuing CAs.
2. Restart and validate web and worker.
3. Rotate the RGW serving certificate.
4. Publish the new-only CA bundle, restart, and validate again.
5. Record ConfigMap resource versions, CA SHA-256 hashes, exact ODF/Ceph
versions, and evidence—never credential values.
See [Storage Health and Troubleshooting](/en/deployment/storage-health-troubleshooting)
and the in-repository
`k8s/overlays/openshift-odf-rgw/README.md` for overlay details.
# Enterprise Storage Overview
Source: https://docs.casebender.com/en/deployment/storage-overview
Architecture and operator entry point for CaseBender object storage
CaseBender stores attachments, evidence, exports, quarantine objects, and
ephemeral canaries in file/object storage. New installs default to a local
Docker volume. You can keep that volume with any license, or point CaseBender
at customer-owned S3, GCS, or Azure. See
[Local Storage Limitations](/en/deployment/storage-local).
PostgreSQL keeps durable object identity, exact provider version, integrity,
scanner, retention, hold, migration, and lifecycle state.
## Architecture
Every deployment defines three profiles:
* `quarantine` receives user-controlled uploads;
* `records` holds scanner-approved durable data and generated exports; and
* `ephemeral` holds canaries and short-lived objects.
The shared `@cbr/storage` boundary implements canonical adapters `s3`, `gcs`,
`azure`, and `local`. Runtime operations include health, upload, download,
exists, list, metadata, copy, delete, retention, and legal hold. Runtime never
creates or configures buckets/containers and never generates signed URLs.
User uploads are written behind a durable upload intent, read back and
SHA-256-verified, scanned by external `clamd`, and copied to `records` only
after a clean verdict. Durable mutation, migration, and reconciliation workers
retry idempotently and expose dead-letter/integrity telemetry.
## Start here
Current machine-readable support and qualification status
Compare live certification requirements and evidence levels
Quarantine, scanning, integrity, encryption, WORM, and secret controls
Protect PostgreSQL and exact object versions as one set
Copy-first cutover, ledger verification, source retention, and rollback
Readiness categories, canary, scanner, CA, permissions, and dead letters
## Provider guidance
External OBC or standalone RGW with private CA and restricted egress
Existing buckets and workload identity
Existing buckets and Workload Identity
Existing containers and Managed Identity
Exact-product/version live certification policy
Development-only local storage and legacy MinIO migration
Adapter or emulator success does not equal live product certification. Current
ODF/Ceph RGW is qualification-ready but awaits customer credential-gated
exact-version evidence.
# Storage Provider Selection and Certification
Source: https://docs.casebender.com/en/deployment/storage-provider-selection
Select a provider without confusing adapter compatibility with live certification
Select storage by operational requirements first, then confirm the release's
machine-readable support declaration. CaseBender does not treat every backend
implemented by an SDK as release-certified.
## Selection flow
1. Choose an external, customer-managed service reachable by both web and
worker.
2. Provision separate `quarantine`, `records`, and `ephemeral` locations.
3. Confirm identity, TLS/private CA, encryption, versioning, retention, legal
hold, audit logging, egress, backup, and restore requirements.
4. Compare the exact product profile with
`scripts/storage/certification-matrix.json`.
5. Run live qualification against the exact product/version from the workload
network.
6. Sign and retain sanitized evidence with the release record.
## Current matrix interpretation
| Matrix ID | Runtime adapter | Declared supported | Required mode | Operator meaning |
| ---------------------- | --------------- | ------------------ | ------------- | -------------------------------------------------------------- |
| `openshift-odf-rgw` | `s3` | Yes | `live` | Support target only after exact ODF/Ceph live evidence passes |
| `aws-s3` | `s3` | No | `live` | Implemented adapter; do not claim release certification |
| `google-cloud-storage` | `gcs` | No | `live` | Implemented adapter; do not claim release certification |
| `azure-blob` | `azure` | No | `live` | Implemented adapter; do not describe Azure as unsupported code |
| `local-development` | `local` | No | `unit` | Development/single-node testing only |
Current ODF/Ceph live evidence is blocked on customer credentials. It is
configured and qualification-ready, not certified. Update customer-facing
status only after the release validator accepts signed exact-version evidence.
## Evidence levels
* **Unit** proves local adapter behavior in controlled code tests.
* **Emulator** proves SDK and contract compatibility with an emulator's subset.
* **Live** proves the required operations against a named product and exact
version in the intended network, trust, identity, and policy context.
Emulator results can never satisfy a matrix entry whose
`requiredCertification` is `live`. Product family names such as “S3
compatible,” “Ceph,” or “Azure Blob” are insufficient without an exact target
version and evidence digest.
Emulator compatibility is not live certification.
## Validate the matrix
```bash theme={null}
node scripts/storage/validate-certification-matrix.mjs
node --test scripts/storage/certification-matrix.test.mjs
# Release use requires a sanitized evidence JSON document.
node scripts/storage/validate-certification-matrix.mjs \
--release \
--evidence ''
```
Start from `scripts/storage/certification-evidence.template.json`. Never add
credentials, tokens, connection strings, private keys, object contents,
customer object names, or signed URLs to evidence.
## Configuration examples
For production, prefer a mode-`0400` or `0600` mounted
`STORAGE_CONFIG_FILE`. This shape is illustrative:
```json theme={null}
{
"profiles": {
"quarantine": { "provider": "s3", "bucket": "", "region": "" },
"records": { "provider": "s3", "bucket": "", "region": "", "requireWorm": true },
"ephemeral": { "provider": "s3", "bucket": "", "region": "" }
}
}
```
The complete strict profile schema is documented in the provider pages. Do not
put access keys in documentation or commit a populated configuration file.
## Requalification triggers
Re-run live evidence after changing any of:
* CaseBender release or storage SDK;
* provider, ODF, Ceph, account, or API version;
* bucket/container security, versioning, retention, or immutability;
* identity, role, credential, endpoint, private CA, or egress policy;
* scanner/promotion boundary; or
* backup, migration, and restore tooling.
Related guidance:
* [Enterprise Storage Support Policy](/en/deployment/storage-support-policy)
* [S3-Compatible Certification](/en/deployment/storage-s3-compatible)
* [Storage Release Security](/en/deployment/storage-release-security)
# Storage Release Security
Source: https://docs.casebender.com/en/deployment/storage-release-security
Release qualification, SBOM review, and signed storage evidence
Storage support is qualified per CaseBender release, provider adapter, and
deployment profile. A provider name alone is not sufficient evidence.
## Release gate
Before publishing an on-premises or OpenShift release:
1. Pin every image by digest in the release manifest.
2. Generate a CycloneDX or SPDX SBOM for each image and the source bundle.
3. Sign images and attest SBOMs with the release identity.
4. Scan the exact published/mirrored digests, including OS and language packages.
5. Review storage SDKs, TLS libraries, CA bundles, and transitive dependencies.
6. Run provider contract, integrity, migration, backup/restore, and rollback
tests for every provider listed as supported by that release.
7. Record exceptions with owner, exploitability, compensating control, expiry,
and approval. Do not suppress an entire package family.
The repository's release workflows already produce SBOM and signature evidence,
and `deploy/verify-images.sh` verifies image signatures, CycloneDX attestations,
and vulnerability policy. Use those controls against each digest after mirroring
as well as before export.
## Consumer verification
Obtain the release manifest, checksums, Sigstore identity/issuer policy, SBOMs,
and attestations through a separate trusted channel. Then:
```sh theme={null}
cosign verify \
--certificate-identity-regexp '' \
--certificate-oidc-issuer '' \
registry.example.com/casebender/webapp@sha256:
cosign verify-attestation \
--type cyclonedx \
--certificate-identity-regexp '' \
--certificate-oidc-issuer '' \
registry.example.com/casebender/webapp@sha256:
trivy image --severity HIGH,CRITICAL \
registry.example.com/casebender/webapp@sha256:
```
Use the exact identity and issuer from signed release notes, not these
placeholders. Verification failure is a release blocker. Preserve transparency
log evidence when connected; for disconnected verification, transfer the signed
bundle and public trust material through the approved process.
## Storage-specific SBOM review
Confirm the SBOM contains the adapters selected at runtime and review:
* historical MinIO components only in legacy source/recovery artifacts; the
production runtime must not contain the native `minio` package;
* `@aws-sdk/client-s3` for S3; a presigner dependency must not imply enabled
signed-URL behavior;
* `@google-cloud/storage` and authentication libraries for GCS;
* `@azure/storage-blob` and `@azure/identity` for Azure;
* Node.js/OpenSSL and the image CA bundle;
* CLI/tool images used for backup, migration, and validation.
An installed but unselected adapter still contributes reachable package risk and
must remain in SBOM and vulnerability review. Conversely, SBOM presence does not
prove a product/version is certified. Azure is implemented under canonical
runtime ID `azure`, but the current matrix does not declare `azure-blob`
release-supported.
## Release evidence record
Retain:
* source revision, immutable image digests, SBOM hashes, signatures, and
verification output;
* scanner databases/tool versions and approved vulnerability exceptions;
* provider/product versions, endpoint TLS protocol/cipher/issuer, and CA hash;
* sanitized provider contract and SHA-256 integrity results;
* migration copy/check logs and rollback result;
* backup consistency point, restore test, measured RPO/RTO;
* OpenShift version, SCC review, rendered manifests, CNI/CSI versions, and
arbitrary-UID `/tmp`/`/data` write tests.
Never include access keys, secret values, presigned URLs, private keys, database
URLs, customer object names, or object contents in release evidence or support
bundles.
## Security response
When a storage SDK or provider vulnerability is disclosed, determine whether the
affected code and configuration are present and reachable, publish a scoped
advisory, update affected images/SBOMs, and re-run contract and restore tests.
Provider retirement is a product lifecycle decision with explicit notice,
migration guidance, and support dates. Current CaseBender guidance treats a
legacy MinIO deployment only as an external migration/rollback source; this
policy does not invent a customer support end date beyond an approved customer
change plan.
# S3-Compatible Storage Certification
Source: https://docs.casebender.com/en/deployment/storage-s3-compatible
Qualification policy for non-AWS products using the CaseBender S3 adapter
An S3-compatible API is not automatically equivalent to AWS S3 and is not
automatically supported. Certify each product, exact version, endpoint mode,
bucket policy, and CaseBender release independently.
## Required contract
The release matrix is authoritative. A candidate commonly needs:
* verified HTTPS, including the deployed private CA path;
* access to an existing bucket without bucket-administration permission;
* upload, HEAD/metadata, download, SHA-256 integrity, copy, pagination,
conditional create, versioning, delete, and delete-marker behavior;
* server-side encryption;
* retention and legal hold when required for the `records` profile; and
* cleanup limited to a unique test prefix and exact versions.
Do not infer capability from an advertised S3 API level. Conditional writes,
checksum headers, version IDs, copy semantics, delete markers, Object Lock, and
private-CA behavior differ among products and versions.
## Qualification procedure
1. Record the product name and exact server version, CaseBender revision/image
digests, endpoint mode, CA digest, bucket policy, and identity policy.
2. Use pre-created dedicated test buckets or a dedicated prefix.
3. Run from the same network, DNS, proxy, CA, and identity context as the web
and worker.
4. Set each capability flag truthfully. `false` means skipped and cannot satisfy
a required matrix operation.
5. Run the application upload/quarantine/scan/promote/download/delete lifecycle.
6. Exercise backup, restore, migration, rollback, retention, and legal-hold
workflows required by the customer.
7. Sanitize, hash, review, and sign the evidence bundle.
For Ceph RGW:
```bash theme={null}
STORAGE_TEST_ENDPOINT='https://' \
STORAGE_TEST_BUCKET='' \
AWS_REGION='' \
STORAGE_TEST_CA_BUNDLE='' \
STORAGE_TEST_ODF_VERSION='' \
STORAGE_TEST_CEPH_VERSION='' \
STORAGE_TEST_CAP_METADATA=true \
STORAGE_TEST_CAP_PAGINATION=true \
STORAGE_TEST_CAP_COPY=true \
STORAGE_TEST_CAP_CONDITIONAL_CREATE='' \
STORAGE_TEST_CAP_VERSIONING='' \
STORAGE_TEST_CAP_DELETE_MARKERS='' \
STORAGE_TEST_CAP_ENCRYPTION=true \
STORAGE_TEST_CAP_OBJECT_LOCK='' \
./scripts/storage/validate-ceph-rgw.sh
```
The general smoke contract is:
```bash theme={null}
STORAGE_TEST_PROVIDER=s3 \
STORAGE_TEST_ENDPOINT='https://' \
STORAGE_TEST_BUCKET='' \
AWS_REGION='' \
./scripts/storage/validate-storage.sh
```
The general script is supplementary and does not cover the complete
exact-version release gate.
## Evidence rules
Use `scripts/storage/certification-evidence.template.json` and validate with:
```bash theme={null}
node scripts/storage/validate-certification-matrix.mjs \
--release \
--evidence ''
```
Evidence must name an exact target version and include a digest. It must not
contain access keys, session tokens, connection strings, private keys, signed
URLs, customer object names, or object contents.
## Emulator limitation
`./scripts/storage/run-emulator-contracts.sh s3` checks the S3 adapter against
LocalStack. It creates an emulator artifact that explicitly says it is not live
certification. Never reuse that result for Ceph RGW, MinIO, AWS S3, or another
S3-compatible product.
## Change control
Requalify after any server upgrade, gateway/configuration change, TLS/CA
rotation, identity/policy change, versioning/Object Lock change, network/proxy
change, CaseBender release, or storage SDK update.
See [Provider Selection and Certification](/en/deployment/storage-provider-selection)
and [OpenShift ODF and Ceph RGW](/en/deployment/storage-openshift-odf-rgw).
# Storage Security Baseline
Source: https://docs.casebender.com/en/deployment/storage-security-baseline
Mandatory controls for uploads, object integrity, access, retention, and telemetry
Apply this baseline to every production storage profile and validate it in the
customer environment.
## External storage and identity
* Use only pre-created customer-owned external buckets or containers.
* Deny public access and account-wide administration.
* Use workload identity/default credential chains with the narrowest
bucket/container and prefix permissions required by web and worker.
* Keep administration, preflight attestation, runtime object operations,
migration, and retention responsibilities separate where the platform
permits.
* Store secrets in the platform secret manager. Never put them in source,
ConfigMaps, images, shell arguments/history, logs, telemetry, support bundles,
or certification evidence.
* Keep TLS verification enabled. Mount private CA files read-only and rotate
them with an overlap procedure.
Runtime adapters perform data-plane operations only. They must not create,
delete, or configure storage locations.
## Three purpose profiles
* `quarantine`: all user-controlled uploads enter here.
* `records`: only scanner-approved user uploads and narrowly defined trusted
server-generated exports become available here.
* `ephemeral`: deep canaries and short-lived data with a bounded lifecycle.
Use different buckets/containers when policy separation is required. Do not
grant end users direct object-store access.
## Malware scanning fails closed
Production requires external `clamd` through `CLAMD_SOCKET_PATH` or
`CLAMD_HOST`. Remote scanner TLS uses `CLAMD_TLS=true` and
`CLAMD_CA_FILE`; a plaintext private-network exception is an explicit risk
exception, not the default.
CaseBender calculates SHA-256, writes an upload intent, reads the exact object
back, and queues verification. If the scanner is unavailable, times out,
returns malformed output, or cannot scan the configured size, the object stays
quarantined. Retries are durable; exhaustion becomes a dead letter. Only a
terminal `CLEAN` verdict permits copy to `records`.
An `INFECTED` result remains quarantined and creates a sensitive security audit
event. Never download a live malware sample for troubleshooting.
## Intentional malware samples
Authorized testing may store a sample with content trust `MALWARE_SAMPLE` and
`quarantineOnly`. It remains quarantined, is never promoted, and has scan state
`SKIPPED`. Use inert EICAR-equivalent fixtures where possible. Require written
authorization, isolated handling, approved retention/destruction, and no
support-ticket attachment. Do not weaken scanning policy to make a test pass.
## Integrity and exact versions
* Persist application SHA-256, size, provider checksum, and provider
version/generation when available.
* Verify downloaded bytes after upload, promotion, migration, backup, and
restore.
* Treat ETags as opaque; multipart/encrypted ETags may not be MD5.
* Use conditional create to prevent overwrite races.
* Address retention, legal hold, restore, and migration by exact object
version—not a floating latest object.
* Alert on `storage.checksum_mismatch`, missing expected objects, and confirmed
orphans.
## Encryption, WORM, and legal hold
Require TLS and provider-managed server-side encryption. Use customer-managed
keys when mandated and verify key rotation/recovery separately.
For regulated `records`, set `requireWorm: true` and
`STORAGE_REQUIRE_WORM=true`, then qualify provider versioning, object
retention/immutability, and legal hold. Readiness fails with category
`capability` when these controls are absent. CaseBender does not bypass
governance retention by default, and compliance retention intentionally blocks
early deletion.
WORM capability in an SDK is not proof that the bucket/container was created
with the required immutable settings.
## No signed URLs
CaseBender storage adapters do not generate presigned S3 URLs, GCS signed URLs,
or Azure SAS URLs. Downloads must pass through CaseBender authentication,
authorization, tenant checks, lifecycle checks, scanner approval, and audit
boundaries.
## Health
* `/api/health/live` is process-only and has no external dependency.
* `/api/health/ready` checks configured providers and requires a fresh deep
write/read/copy/delete canary on `ephemeral`.
* The response exposes only sanitized categories:
`configuration`, `authentication`, `tls`, `storage`, `capability`, or
`canary_stale`.
Never include endpoint credentials, object keys, bucket names, customer names,
or provider exception messages in a public health response.
## Telemetry and privacy
Monitor aggregated provider, operation, result, latency, byte, scanner,
quarantine, outbox, migration, reconciliation, and readiness metrics. Apply
least-access controls and retention to observability data.
Logs and metric labels may include a canonical provider and operation. They
must not include credentials, tokens, signed URLs, connection strings, private
keys, file contents, customer object names, or sensitive object keys. Sanitize
errors before persistence and support export.
See [Storage Health and Troubleshooting](/en/deployment/storage-health-troubleshooting)
and [Backup and Restore](/en/deployment/storage-backup-restore).
# Enterprise Storage Support Policy
Source: https://docs.casebender.com/en/deployment/storage-support-policy
Current CaseBender storage support, qualification, and lifecycle policy
CaseBender storage is either a local Docker volume (the install default) or
customer-owned external object storage. The application performs object
data-plane operations only. It never creates, deletes, or configures a bucket
or container at runtime. License (community or enterprise) does not choose the
storage backend.
## Current release status
The machine-readable authority is
`scripts/storage/certification-matrix.json`:
| Product profile | Adapter | Current declaration | Evidence required |
| ----------------------- | ------- | --------------------------------------------------- | -------------------------------------------------------------------- |
| OpenShift ODF/Ceph RGW | `s3` | Declared support target; qualification-ready | Passing live evidence for the exact ODF/Ceph and CaseBender versions |
| AWS S3 | `s3` | Adapter implemented; not declared release-supported | Passing live AWS evidence |
| Google Cloud Storage | `gcs` | Adapter implemented; not declared release-supported | Passing live GCS evidence |
| Azure Blob Storage | `azure` | Adapter implemented; not declared release-supported | Passing live Azure evidence |
| Local filesystem | `local` | Default install volume; single-host | Unit, local contract tests, Compose volume |
| MinIO Community Edition | none | Legacy migration source only | Not available for new production use |
The repository has emulator results, but emulator compatibility is not live
certification. Current ODF/Ceph RGW live certification is pending
customer-provided credentials and exact-version evidence. The profile is
configured and qualification-ready, not certified.
“Implemented” means an adapter exists for object operations. “Declared
supported” means the release matrix selects a product profile for a support
gate. “Certified” additionally requires complete, signed live evidence for the
exact product and version. Never infer certification from an adapter name,
emulator run, Kubernetes render, or another customer's result.
## Configuration contract
Use a mounted `STORAGE_CONFIG_FILE` (preferred) or `STORAGE_CONFIG_JSON` with
three profiles: `quarantine`, `records`, and `ephemeral`. The legacy
single-profile bridge uses only these canonical provider IDs and variables:
* `s3`: `S3_BUCKET`, `AWS_REGION`, optional HTTPS `S3_ENDPOINT`
* `gcs`: `GCS_BUCKET`, optional `GCS_PROJECT_ID`
* `azure`: `AZURE_STORAGE_ACCOUNT`, `AZURE_CONTAINER`
* `local`: `STORAGE_PATH` (Compose default `/data`)
`azure-blob`, `AWS_S3_BUCKET`, and `AZURE_STORAGE_CONTAINER` are not valid
runtime names. Installations must set an explicit storage provider. MinIO and
HTTP custom endpoints are rejected. Local volume storage is a named Docker
volume, independent of license.
Use workload identity or the provider's default credential chain. Static S3
keys, GCS key files, Azure shared keys, and Azure connection strings are
compatibility modes only. Store any credentials in the platform secret manager;
never place them in source, ConfigMaps, images, shell history, logs, evidence,
or support bundles.
## Required production boundary
* Use pre-created external buckets or containers with no public access.
* Separate quarantine, durable records, and ephemeral objects so retention,
scanner, and expiry policy can differ.
* Keep TLS verification enabled; mount private CA bundles when required.
* Require encryption at rest and in transit, versioning, backups, and
application SHA-256 verification.
* Enable and qualify retention/legal-hold controls when the deployment requires
WORM. Exact object versions are mandatory for retention and hold operations.
* Do not enable signed URL, presigned URL, or SAS generation. Downloads pass
through authenticated CaseBender authorization.
* Configure external `clamd`; user uploads remain quarantined and unavailable
when scanning cannot produce a terminal clean verdict.
* Monitor readiness, deep-canary age, mutation dead letters, quarantine age,
missing objects, confirmed orphans, checksum failures, latency, and capacity.
See [Storage Security Baseline](/en/deployment/storage-security-baseline) and
[Storage Health and Troubleshooting](/en/deployment/storage-health-troubleshooting).
## Qualification and change control
Validate from the same network, identity, endpoint, and CA context as the web
and worker workloads. Re-run qualification after a CaseBender upgrade, provider
upgrade, bucket-policy change, credential rotation, CA rotation, network-policy
change, or WORM change.
```bash theme={null}
node scripts/storage/validate-certification-matrix.mjs
node --test scripts/storage/certification-matrix.test.mjs
```
Provider-specific live validation and signed evidence are required in addition
to repository tests. See
[Provider Selection and Certification](/en/deployment/storage-provider-selection)
and [S3-Compatible Certification](/en/deployment/storage-s3-compatible).
## Lifecycle references
* [OpenShift ODF/Ceph RGW](/en/deployment/storage-openshift-odf-rgw)
* [AWS S3](/en/deployment/aws)
* [Google Cloud Storage](/en/deployment/google-cloud-run)
* [Azure Blob Storage](/en/deployment/azure)
* [Local Storage Limitations](/en/deployment/storage-local)
* [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle)
* [Backup and Restore](/en/deployment/storage-backup-restore)
* [Storage Migration](/en/deployment/storage-migration-runbook)
# Upgrading CaseBender
Source: https://docs.casebender.com/en/deployment/upgrading
Safely upgrade your CaseBender deployment to the latest version without losing data, licenses, or credentials.
## Overview
CaseBender ships as a public, source-free Community release bundle and a
matching set of versioned container images. Customers do not need access to the
private source repository.
Upgrading means verifying the new bundle, updating the deployment files in the
existing installation directory, pulling the pinned images, and recreating the
containers. Data and configuration remain in named Docker volumes and `.env`.
Use a pinned target version. Never change a production deployment to a mutable
`latest` tag during an upgrade.
If the current installation uses `docker-compose.yml` with `app`, `db`, or an
embedded MinIO service, first follow
[Migrate a Legacy Docker Compose Installation](/en/deployment/legacy-compose-migration).
The procedure below is only for installations already managed by the signed
bundle.
Database migrations and default-data seeding run automatically on startup after
every upgrade. You do not need to run any migration commands manually.
## What persists across upgrades
| What | Where it lives | Preserved by |
| ------------------------------ | ------------------------------------------- | ------------------------------------- |
| Cases, alerts, users, settings | PostgreSQL | `pgdata` volume |
| Uploaded files / attachments | `/data` | `casebender_data` volume |
| Queue / cache state | Redis | `redis_data` volume |
| Search index (optional) | OpenSearch | `opensearch_data` volume |
| License secret | Environment configuration | `.env` (`LICENSE_SECRET_KEY`) |
| Installation ID | Environment configuration and secret volume | `.env` (`CASEBENDER_INSTALLATION_ID`) |
| Audit-chain HMAC key | Environment configuration | `AUDIT_INTEGRITY_SECRET` in `.env` |
| Environment configuration | `.env` | your `.env` file |
Paid licenses are bound to the Installation ID. After an upgrade, confirm
**Settings → License** or `./casebender license` still shows the same ID. See
[License](/en/settings/license). Do not send `LICENSE_SECRET_KEY` to CaseBender
to request a paid key.
Never run `docker compose down -v` on a production system. The `-v` flag deletes
all named volumes — your database, license, and files. Without those volumes, the
next start creates a fresh database and a new activation state.
## Upgrade procedure (Docker Compose)
Run the commands from the existing installation directory. Do not copy
`release.env`, Compose files, or the CLI by hand. `./casebender upgrade` applies
the signed bundle (CLI, Compose, Nginx stock file, preflight/canary,
`release.env`, and `release-manifest.json`) and never overwrites `.env`.
```bash theme={null}
# Back up PostgreSQL
docker compose --env-file .env -f docker-compose.prod.yml exec -T postgres \
sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' \
> casebender-backup-$(date +%F).sql
# Keep a copy of your configuration
cp .env .env.backup
```
Verify that the backup can be read and store it outside the Docker host.
On a connected host, download, verify (SHA-256 and Cosign), and apply a
pinned version in one command. `v1.0.9` is also accepted. Never use `latest`.
```bash theme={null}
./casebender upgrade --version 1.0.9
```
The default download base is the public CaseBender Blob store used by the
[Quickstart](/en/quickstart). Override it with `CASEBENDER_RELEASE_BASE_URL`
when you mirror artifacts internally. Cosign must be installed for a
`--version` upgrade.
On an air-gapped host, sneakernet the versioned archive (and, if you have
them, the `.sha256` and `.sigstore.json` sidecars). Then apply the local tar.
Inner `SHA256SUMS` is required. Cosign runs only when a `.sigstore.json`
sidecar sits next to the archive.
```bash theme={null}
./casebender upgrade --offline ./casebender-onprem-v1.0.9.tar.gz
```
Bare `./casebender upgrade` does not pull images. It prints the current pin
and the two commands above. To pull and recreate the **current** pin after a
failed recreate, use `./casebender upgrade --reapply` (add `--offline` when
images are already loaded).
If this installation's CLI does not accept `--version`, copy only `casebender`
from the verified bundle into this directory once, then rerun the command.
The managed path writes `.env.pre-upgrade`, copies pinned release metadata
into `.env` without replacing secrets, preserves an existing
`AUDIT_INTEGRITY_SECRET` or generates it once for an older installation, runs
preflight, pulls the exact images unless `--offline`, and recreates containers
without building source.
If `deploy/nginx/nginx.conf` was customized, the CLI writes
`nginx.conf.pre-upgrade` and installs the stock release file. Re-apply site
TLS and proxy settings from that backup. Include `.env` and
`.env.pre-upgrade` in the protected backup set.
```bash theme={null}
./casebender logs
```
Migrations and seeding run on boot — wait for the app to report healthy.
## Verify after upgrading
* Sign in and confirm your existing cases, alerts, and users are present.
* Confirm your login still works (your admin password is unchanged).
* Confirm the deployment remains `ACTIVE`; an existing installation must not
display `/setup`.
* Confirm organization, role, TLP, API-key scope, and integration egress checks.
* Update a non-critical test alert and verify its audit entry appears without an
integrity configuration error.
* Check the worker is processing jobs:
```bash theme={null}
docker compose logs worker | tail
```
Run the automated canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
## Rollback
Do not start older application images against a schema that they do not support.
Use the release note's declared rollback path.
When the release notes explicitly confirm backward schema compatibility, the
managed rollback restores the previous immutable image pin saved immediately
before the upgrade:
```bash theme={null}
./casebender rollback --confirm-schema-compatible
```
For an air-gapped host whose previous images are still loaded, add `--offline`.
The command preserves the failed release configuration as `.env.pre-rollback`.
If a database migration is not backward compatible, do not use image-only
rollback. Stop the stack and restore the pre-upgrade database and matching
volumes before starting the previous pinned image set:
```bash theme={null}
./casebender down
# Restore the previous verified bundle's deployment files in this same directory,
# then update .env from that bundle without starting application containers:
./casebender pin-release
docker compose --env-file .env -f docker-compose.prod.yml up -d postgres
# Restore into the database version documented for the previous release
cat casebender-backup-YYYY-MM-DD.sql |
docker compose --env-file .env -f docker-compose.prod.yml exec -T postgres \
sh -c 'psql -U "$POSTGRES_USER" "$POSTGRES_DB"'
./casebender up
```
Always upgrade a staging environment first, and take a fresh database backup
immediately before upgrading production.
## Common upgrade mistakes
The two most common problems both come from losing state:
* **Changing the Compose project name or directory.** Docker derives volume names
from the project. Renaming the folder or using a different `-p` project name
points Compose at *new, empty* volumes. Always upgrade from the same
directory/project so your existing volumes are reused.
* **Replacing `.env`.** The bundle's `release.env` contains only pinned release
metadata. It must not replace the installation's secret-bearing `.env`.
* **Running only `docker compose pull`.** A raw image pull bypasses managed
secret recovery, release pinning, preflight, and backup creation. Always run
`./casebender upgrade --version ` or
`./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz`.
* **Rotating `AUDIT_INTEGRITY_SECRET`.** A new value cannot verify audit entries
written with the previous key. Preserve the installation-specific value
across upgrades, rollbacks, and restores.
## Activation compatibility
The activation migration is idempotent:
* databases with existing users become `ACTIVE`;
* existing passwords, users, roles, organizations, cases, and API keys are not
changed;
* no second administrator is created; and
* only a genuinely empty installation enters first-run activation.
Validate this behavior against a sanitized copy of each supported customer
database before promotion.
## Desktop Installer
If you deployed with the Desktop Installer, use the app's built-in update flow —
it pulls the latest images and recreates services while preserving your data
directory, `.env`, and license key.
## Google Cloud Run
Cloud Run upgrades deploy a new revision. Because Cloud Run has an ephemeral
filesystem, the license secret must be provided via **Secret Manager** as
`LICENSE_SECRET_KEY` so it persists across revisions. Redeploy against your
existing Cloud SQL instance and secrets:
```bash theme={null}
gcloud run deploy casebender-web --image --region
```
Migrations run automatically on the new revision.
# Introduction
Source: https://docs.casebender.com/en/introduction
Welcome to CaseBender Documentation
## Welcome to CaseBender
CaseBender is a powerful case management and alert handling platform designed to streamline your security operations. Our platform helps teams efficiently manage, investigate, and respond to security alerts and cases.
## Key Features
Efficiently handle and process security alerts with advanced filtering and
automation
Create and manage cases with comprehensive tracking and collaboration
features
Automate repetitive tasks and streamline your security operations
Connect with your existing security tools and data sources
Enterprise-grade security with 20+ controls and 10+ compliance frameworks
External object storage, quarantine, integrity, certification, and recovery
## Getting Started
Get started with CaseBender by following our comprehensive guides:
Get up and running with CaseBender in minutes
Learn about the fundamental concepts of CaseBender
# Quickstart Guide
Source: https://docs.casebender.com/en/quickstart
Securely deploy CaseBender on-premises with Docker Compose
This guide is the supported command-line installation path for an on-premises
CaseBender deployment. It does not require public internet access after the
container images have been made available in your environment.
Prefer a graphical workflow? The [Desktop Installer](/en/deployment/desktop-installer)
uses the same first-run activation model.
## Prerequisites
* Linux, macOS, or Windows with WSL 2
* Docker Engine 20.10+ and Docker Compose v2+
* On Apple Silicon or other arm64 hosts, Docker must emulate **linux/amd64**
(Docker Desktop Rosetta or QEMU). CaseBender application images and the
bundled ClamAV scanner are amd64-only. First boot can take several minutes
while the web container runs database migrations and seed data.
* Node.js 20+ on the **host** (`./casebender setup`, `preflight`, `up`,
`upgrade`, and the canary check invoke Node; `init` alone does not)
* OpenSSL
* Cosign (bundle signature verification only; not required to run `init` or `up`)
* **8 GB RAM minimum**, 16 GB recommended (web, API, workers, PostgreSQL, Redis,
and the bundled ClamAV scanner)
* Ports 80 and 443 free on the host
* For production: a DNS name and trusted TLS certificate for the CaseBender host
* Internet access to download the public Community bundle and container images,
or an approved process for mirroring the release's exact image digests
The bundle does not include container images. `./casebender up` pulls the
pinned tags from the registry in `release.env`. If that registry requires
authentication, run `docker login` for it before `up`.
Do not copy credentials from this guide into an installation. CaseBender
generates installation-specific secrets.
## 1. Download and verify the Community bundle
The CaseBender source repository is private and is **not** part of the customer
installation process. The public, source-free bundle contains the production
Compose definition, the `casebender` management command, preflight and canary
checks, Nginx configuration, and pinned release metadata.
Source-free Docker Compose installation bundle
Download the archive, checksum, and Sigstore verification bundle:
```bash theme={null}
BASE_URL="https://p5lt3orxujizwets.public.blob.vercel-storage.com/onprem/latest"
curl -fLO "$BASE_URL/casebender-onprem.tar.gz"
curl -fLO "$BASE_URL/casebender-onprem.tar.gz.sha256"
curl -fLO "$BASE_URL/casebender-onprem.tar.gz.sigstore.json"
curl -fLO "$BASE_URL/release-manifest.json"
sha256sum -c casebender-onprem.tar.gz.sha256
cosign verify-blob \
--bundle casebender-onprem.tar.gz.sigstore.json \
--certificate-identity-regexp \
'^https://github\.com/casebender/webapp/\.github/workflows/release-onprem\.yml@refs/(tags/v[0-9]+\.[0-9]+\.[0-9]+([._-][A-Za-z0-9.-]+)?|heads/main)$' \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
casebender-onprem.tar.gz
mkdir casebender-onprem
tar -xzf casebender-onprem.tar.gz \
-C casebender-onprem \
--strip-components=1
cmp release-manifest.json casebender-onprem/release-manifest.json
cd casebender-onprem
sha256sum -c SHA256SUMS
```
On macOS, use `shasum -a 256 -c` instead of each `sha256sum -c`.
The signed archive contains the same `release-manifest.json`; compare it with
the separately downloaded manifest and retain it with your deployment records.
It records the exact source commit and signed digest for every container image
in the release.
The Community download does not currently include an offline image archive.
For an air-gapped installation, mirror or export all seven exact image digests
from `release-manifest.json` through your approved software-import process and
load them into Docker or your internal registry before running
`./casebender up --offline`.
## 2. Initialize the installation
### Guided setup (recommended)
On a terminal, one command prompts for the public HTTPS URL, writes `.env`,
starts the stack, and prints a boxed one-time setup code:
```bash theme={null}
./casebender setup
```
Use `--yes` or `CASEBENDER_NONINTERACTIVE=1` to skip prompts. Air-gapped hosts
that already have images loaded use `./casebender setup --offline`.
### Default local volume
The first install uses local file storage. License (community or enterprise)
does not change that. Non-interactive initialize with no storage variables:
```bash theme={null}
./casebender init
```
This writes `STORAGE_PROVIDER=local`, stores files on a named Docker volume at
`/data`, and starts a bundled ClamAV scanner on the internal Compose network.
An in-app banner notes that files live on this host. You can keep this after
applying an enterprise license, or switch later to object storage.
### Optional object storage
```bash theme={null}
# Example: existing S3 bucket with ECS/host workload identity
STORAGE_PROVIDER=s3 \
S3_BUCKET=customer-casebender-records \
AWS_REGION=us-east-1 \
MALWARE_SCANNER_PROVIDER=clamd \
CLAMD_HOST=scanner.internal.example \
./casebender init
```
GCS uses `GCS_BUCKET`/`GCS_PROJECT_ID` with ADC. Azure uses
`AZURE_STORAGE_ACCOUNT`/`AZURE_CONTAINER` with Managed Identity. A mounted
`STORAGE_CONFIG_FILE` or inline `STORAGE_CONFIG_JSON` can define separate
quarantine, records, and ephemeral profiles. MinIO is not a supported provider
and is not embedded in Compose.
Initialization:
* reads the pinned image version and registry from the bundle's `release.env`;
* creates `.env` with unique authentication, database, Redis, and OpenSearch
secrets while preserving the supplied storage configuration;
* keeps secrets out of command output;
* prepares the one-time local activation state; and
* refuses to overwrite an existing `.env` or reset an installation.
Back up `.env` in your approved secret store. Never commit it or send it through
email or chat.
Then set the public HTTPS origin if you did not use `./casebender setup`.
Non-interactive `init` writes `https://localhost`, which is enough only for a
local browser override. Sign-in cookies and later OAuth integrations need the
real URL:
```bash theme={null}
# Replace with the hostname operators will open in a browser.
NEXTAUTH_URL=https://casebender.your-company.example
NEXTAPP_URL=https://casebender.your-company.example
OAUTH_ALLOWED_ORIGINS=https://casebender.your-company.example
```
If web logs show `Failed to connect to database` while waiting for host `db`,
this release is older than the Postgres service rename. Add the following to
`.env` **and** to the `web` service `environment` in `docker-compose.prod.yml`,
then run `./casebender up` again:
```bash theme={null}
POSTGRES_HOST=postgres
```
## 3. Install TLS certificates
`./casebender init` already writes a temporary self-signed certificate at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
Replace those files with a certificate trusted by client devices before
production use. Keep the self-signed pair only for isolated evaluation; browsers
will warn until you install a trusted chain. A certificate or “connection is
not private” warning on `https://localhost` after `./casebender init` is
expected. Proceed for evaluation, then replace the certificate before
production.
## 4. Run production preflight
```bash theme={null}
./casebender preflight
```
Preflight blocks startup when installation secrets are missing or weak, Redis
is unauthenticated, TLS files are absent, mutable image tags are used, the demo
profile is selected, storage is missing or insecure, malware scanning is not
configured, or a non-proxy service port is published. Local volume storage is
the default (`STORAGE_PROVIDER=local`). Object-storage profiles must use
canonical variables and HTTPS endpoints. Mounted storage profile files must be
absolute paths, valid JSON, and inaccessible to group/other users (mode `0600`).
## 5. Start CaseBender
```bash theme={null}
./casebender up
```
Skip this if you already ran `./casebender setup`. This pulls only the pinned
images identified by `release.env`; it does not clone or build the private
source repository. First `up` prints numbered steps while the web container
runs migrations and seed (often several minutes on ARM under amd64 emulation)
and then prints a boxed one-time setup code with the full `/setup` URL. If
Compose exits before that, the `/setup` page shows **Setup code required**
until you run `./casebender activation-code` against a healthy web container.
Nginx starts only after the web process answers `GET /api/health`. Next.js
printing **Ready** is not the same as storage `/api/health/ready`. If web logs
already show the server started but Compose still shows `casebender-web` as
Waiting (and nginx never starts), start the proxy:
```bash theme={null}
docker start casebender-nginx
```
Then continue with activation. In the extracted Compose file, the web
`healthcheck` URL must be `/api/health`, not `/api/health/ready`.
If `./casebender activation-code` fails with `Cannot find package 'zod'`, Node
ESM cannot see pnpm's nested copy. Create a top-level symlink, then issue the
code. `NODE_PATH` does not work for this ESM CLI.
```bash theme={null}
docker exec casebender-web ln -sfn \
/app/packages/database/node_modules/.pnpm/zod@3.25.76/node_modules/zod \
/app/node_modules/zod
docker exec casebender-web node \
/app/packages/services/dist/bootstrap-cli.js reissue
```
If the `zod@` version differs, pick the path from:
```bash theme={null}
docker exec casebender-web find /app -path '*/node_modules/zod/package.json'
```
If the matching images were already loaded from the air-gapped archive, run:
```bash theme={null}
./casebender up --offline
```
Only Nginx ports 80 and 443 are published. PostgreSQL, Redis, OpenSearch, API,
ingestion, worker, and processor services remain on the internal Compose
network. Default local storage uses a named volume and bundled ClamAV on that
same network. Optional object storage is customer-owned and external to the
Compose stack.
Monitor startup with the management command so local-storage Compose overlays
are included:
```bash theme={null}
./casebender status
./casebender logs
```
## 6. Complete one-time activation
After `./casebender up` or `./casebender setup` prints the boxed setup code,
open the URL shown next to **Open:** (from `NEXTAUTH_URL`) on the **same** host.
To reissue a code:
```bash theme={null}
./casebender activation-code
```
The terminal prints the code as a single copy-paste line and a `CODE=` line for
logs. The code is at least 32 characters, expires after **30 minutes**, allows
five failed attempts, and cannot be reused after activation.
```text theme={null}
https://casebender.your-company.example/setup
```
The setup page is hosted by the on-premises instance. It does **not** contact a
CaseBender public activation service and works in an air-gapped network.
Enter the code, administrator email, display name, and a unique administrator
password (at least 12 characters, with uppercase, lowercase, a digit, and a
symbol). See [First-run setup](/en/deployment/first-run-setup). If the code
expires, run `./casebender activation-code` again; the previous code is
invalidated.
CaseBender does not create a shared production password. The legacy bootstrap
mode is for temporary compatibility only and requires an explicit risk
acknowledgement. Do not enable it for a new installation.
## 7. Verify the deployment
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Then verify:
* the administrator can sign in;
* another organization cannot access its cases, alerts, tasks, attachments, or
audit records;
* API keys cannot request scopes beyond the owner's permissions;
* integration destinations use HTTPS and approved egress;
* backup and restore procedures work.
## Clean start on a new host
Use this sequence when replacing a legacy install with an empty product. It
creates a new database, new encryption keys, and a new first administrator.
Existing cases, users, and integrations are not imported.
1. Leave the legacy directory untouched. Extract this bundle into a **new**
directory so Docker Compose does not reuse the old project name or volumes.
2. Confirm Node.js 20+ (`node -v`) and that ports 80 and 443 are free.
3. `./casebender init` (no storage variables for local volume + bundled ClamAV).
4. Edit `.env` and set `NEXTAUTH_URL`, `NEXTAPP_URL`, and
`OAUTH_ALLOWED_ORIGINS` to `https://`.
5. Replace `deploy/nginx/ssl/` with a trusted certificate, or accept a browser
warning for evaluation only.
6. `./casebender preflight` then `./casebender up`.
7. `./casebender activation-code` and open `https:///setup`.
Do **not** unpack over the legacy `docker-compose.yml` directory, and do **not**
run `./casebender init` where an existing `.env` or named volumes already belong
to a live install. `init` refuses to overwrite `.env`; deleting that file to
force `init` would generate new database passwords against leftover `pgdata`.
Postgres only reads `POSTGRES_PASSWORD` on first initialization, so the new
`.env` cannot log in. `init` now refuses when `pgdata` already exists.
If you already generated a new `.env` against leftover volumes, keep that
`.env` and reset data:
```bash theme={null}
./casebender down --purge-volumes --confirm
./casebender up
```
If you still need the legacy data, stop and follow
[Migrate a Legacy Docker Compose Installation](/en/deployment/legacy-compose-migration)
instead of this clean start.
## Existing installations
When an existing CaseBender database is upgraded, the compatibility migration
marks it `ACTIVE`. Existing users, passwords, roles, organizations, cases, and
API keys remain unchanged. The setup page does not appear and seeding does not
create or reset an administrator.
Take a verified backup and follow [Upgrading CaseBender](/en/deployment/upgrading).
Connected hosts run `./casebender upgrade --version 1.0.9`. Air-gapped hosts
apply a local archive with
`./casebender upgrade --offline ./casebender-onprem-v1.0.9.tar.gz`.
Do not copy `release.env` or Compose files by hand. If the current deployment uses a legacy
`docker-compose.yml` with `app`, `db`, or embedded MinIO services, use
[Migrate a Legacy Docker Compose Installation](/en/deployment/legacy-compose-migration)
instead of treating it as a routine upgrade. Preserve the existing `.env`,
Compose project name, named volumes, attachment storage, and cryptographic
keys. Never run `./casebender init` against an existing installation.
## On-premises private integrations
Outbound integrations require HTTPS and reject loopback, link-local, metadata,
and private destinations by default. To permit a specific internal integration,
add only its exact hostname to:
```bash theme={null}
CASEBENDER_PRIVATE_EGRESS_ALLOWLIST=siem.internal.example,ticketing.internal.example
```
This setting is an allowlist, not a switch to permit all private networks.
## Useful commands
```bash theme={null}
./casebender setup
./casebender preflight
./casebender up
./casebender activation-code
./casebender status
./casebender logs
./casebender down
```
Never use `docker compose down -v` on an installation that contains data. A
clean reinstall that should wipe Postgres uses
`./casebender down --purge-volumes --confirm`.
## Next steps
* [First-run setup](/en/deployment/first-run-setup)
* [License](/en/settings/license)
* [Hardening guide](/en/security/hardening-guide)
* [Upgrading CaseBender](/en/deployment/upgrading)
(`./casebender upgrade --version 1.0.9` or
`./casebender upgrade --offline ./casebender-onprem-v1.0.9.tar.gz`)
* [API keys](/en/settings/account/api-keys)
# Access Control
Source: https://docs.casebender.com/en/security/access-control
Implemented roles, scoped permissions, TLP ceilings, cross-team case grants, and API key scopes in CaseBender.
## Authorization model
CaseBender combines protected system roles, organization-defined roles, resource-and-action permissions, assignment scope, and TLP checks. A user can have multiple role assignments. Authorization is evaluated by the server for the organization and, where applicable, team involved in the request.
* **Platform scope** uses an unscoped `superadmin` assignment.
* **Organization scope** associates a role or direct permission with one organization.
* **Team scope** further associates the assignment with one team in an organization.
* A role supplies a permission template. A direct permission record can add an enabled permission for a user in the applicable organization or team.
A disabled direct permission is not an explicit deny: it disables that direct grant, but it does not remove a permission supplied by a role. Remove or change the role assignment when its template is too broad.
## Fixed role catalog
The database seeds the following 21 protected system roles. Organization administrators can clone or create organization-defined roles without modifying these templates. The capability summary is intentionally high-level; the seeded permission template, assignment scope, and server-side checks determine the effective actions.
| Role key | Intended use | Privileged | TLP ceiling |
| ----------------------- | ---------------------------------------------------------------------------------------------- | ---------- | ---------------- |
| `superadmin` | Global platform administration and full feature access | Yes | TLP:RED |
| `orgadmin` | Organization settings and user management | Yes | TLP:AMBER+STRICT |
| `soc_manager` | SOC team management, metrics, and escalations | Yes | TLP:AMBER+STRICT |
| `soc_lead` | Shift handover and case assignment | No | TLP:AMBER+STRICT |
| `soc_analyst_t3` | Advanced analysis, incident response, and threat hunting | No | TLP:AMBER+STRICT |
| `soc_analyst_t2` | Investigation, detailed analysis, and escalation | No | TLP:AMBER |
| `soc_analyst_t1` | Triage, monitoring, and initial response | No | TLP:AMBER |
| `incident_commander` | Major-incident coordination and oversight | Yes | TLP:RED |
| `threat_hunter` | Proactive, hypothesis-driven threat hunting | No | TLP:AMBER+STRICT |
| `forensics_analyst` | Evidence handling, chain of custody, and forensic analysis | Yes | TLP:RED |
| `vulnerability_analyst` | Vulnerability management and remediation tracking | No | TLP:AMBER |
| `privacy_officer` | Privacy incidents and data-protection oversight | No | TLP:AMBER+STRICT |
| `compliance_officer` | Audit, regulatory compliance, and policy oversight | No | TLP:AMBER+STRICT |
| `legal_counsel` | Legal holds, e-discovery, and litigation support | Yes | TLP:RED |
| `external_collaborator` | Time-bounded access to directly granted cases only | No | TLP:RED |
| `engineering_lead` | Security-remediation coordination with engineering | No | TLP:AMBER |
| `engineering_user` | Assigned engineering tasks and status updates | No | TLP:GREEN |
| `owner` | Legacy team-owner compatibility role; deprecated in favor of `soc_manager` | No | TLP:AMBER |
| `user` | General access to assigned work | No | TLP:GREEN |
| `analyst` | Legacy analyst compatibility role; deprecated in favor of `soc_analyst_t1` or `soc_analyst_t2` | No | TLP:AMBER |
| `readonly` | View access for executives and stakeholders | No | TLP:AMBER |
Do not create an **Integration** user role. Programmatic credentials use API key scopes, described below.
### Privileged markers
Roles and permissions can be marked privileged for audit and policy handling. This marker does not itself provide a user-facing privilege request or approval workflow. Do not assume that dual approval, session recording, break-glass access, or a particular elevation duration is enforced unless your deployment has separately implemented and validated those controls.
## Permission evaluation
Permissions use resource-and-action names such as `caseRead`, `caseUpdate`, `userRoleAssign`, `auditLogExport`, and `apiKeyRotate`.
For a scoped request, CaseBender evaluates:
1. Active role assignments in the applicable organization and team.
2. The permission templates attached to those roles.
3. Enabled direct permissions for the user in the scope being evaluated.
4. The resource's TLP level when the operation performs a TLP-aware check.
`superadmin` is treated as an unscoped all-permissions role. For other users, changing the active organization can change the role and permission set that applies.
## TLP ceilings
CaseBender represents TLP as an ordered scale:
| Value | Label |
| ----- | ---------------- |
| 0 | TLP:CLEAR |
| 1 | TLP:GREEN |
| 2 | TLP:AMBER |
| 3 | TLP:AMBER+STRICT |
| 4 | TLP:RED |
A TLP-aware check compares the resource's value with the maximum role ceiling resolved for that user and request. TLP is an additional restriction: a sufficient ceiling does not grant a missing resource permission or bypass organization, team, or case-access boundaries.
Organization records also carry default and maximum TLP configuration. API keys have their own maximum TLP value. These values are separate from, and do not raise, a human user's role ceiling.
## Cross-team case access
A case can be granted to one user or one team outside its normal ownership boundary. Organization-wide grants are not part of the implemented recipient model.
### Grant taxonomy
| Grant type | Meaning |
| ----------------- | --------------------------------------------------- |
| `TASK_ASSIGNMENT` | Access created because cross-team work was assigned |
| `EXPLICIT_SHARE` | A user or team was explicitly shared into the case |
| `ESCALATION` | Access resulted from case escalation |
| `COLLABORATION` | Access resulted from a collaboration request |
Each grant records who granted it and can include a reason, source entity, and expiration. Expiration is an attribute of any grant, not a separate grant type. Revocation is retained in the grant audit data.
### Access levels
| Access level | Implemented meaning |
| ------------ | ------------------------------------------------------------------- |
| `VIEW` | View case details, tasks, and comments |
| `COMMENT` | View and add case comments |
| `CONTRIBUTE` | View, comment, and work on assigned tasks |
| `FULL` | Perform case operations except delete and administrative operations |
The grant level controls cross-team case access. The user still needs any separately enforced permission and adequate TLP access for the requested operation.
## API keys are separate from user roles
API keys are credentials owned by a user and optionally associated with an organization, but their authorization uses API scopes such as `cases:read`, `alerts:write`, or `api-keys:rotate`. A key also has its own TLP ceiling and lifecycle controls.
* A user role determines whether the user can create or administer keys and which scopes the interface offers.
* The created key carries its selected API scopes; it is not assigned one of the 20 user roles.
* Wildcard and administrative scopes should be reserved for workloads that require them.
* Key tiers describe rate-limit configuration, not an authorization role.
See [API Keys](/en/settings/account/api-keys) for creation, rotation, expiration, status, and scope guidance.
## Related Documentation
* [Authentication](/en/security/authentication) — MFA, SSO, and session management
* [Audit Logging](/en/security/audit-logging) — Access event logging
* [Members](/en/settings/account/members) — User provisioning and role assignment
# Security Architecture
Source: https://docs.casebender.com/en/security/architecture
CaseBender's Zero Trust architecture, service isolation, network segmentation, and multi-tenant security design.
## Zero Trust Architecture
CaseBender implements a Zero Trust security model aligned with NIST SP 800-207. No service, user, or device is implicitly trusted regardless of network location.
### Core Principles
1. **Verify Explicitly**: Every request is authenticated and authorized based on all available data points — identity, device health, location, service identity, and data classification
2. **Least Privilege Access**: Users and services receive the minimum permissions required for their function, with just-in-time elevation for privileged operations
3. **Assume Breach**: The architecture assumes any component can be compromised and limits blast radius through segmentation and isolation
### Device Trust Assessment
Every client device connecting to CaseBender is assessed for trust level:
| Trust Level | Criteria | Access Granted |
| ------------- | ------------------------------------------------------------------ | -------------------------------------------------- |
| **Full** | Managed device, up-to-date OS, EDR active, compliant configuration | All operations including sensitive data |
| **Elevated** | Known device, recent OS, security software present | Standard operations, restricted sensitive data |
| **Standard** | Authenticated user, basic device info available | Read operations, limited write access |
| **Reduced** | Unknown device or outdated security posture | Read-only access, step-up required for any changes |
| **Untrusted** | Failed device checks or suspicious indicators | Access denied, security alert generated |
### Mutual Service Authentication
Microservices within CaseBender authenticate to each other using HMAC-based mutual authentication:
* Each service has a unique identity and signing key
* Every inter-service request includes a cryptographic signature
* Receiving services verify the signature before processing
* Replay attacks are prevented with timestamp-based nonce validation
* Key rotation is automated and does not require service restarts
### Step-Up Authentication
Sensitive operations require re-authentication regardless of existing session validity:
* **Bulk operations**: Deleting or modifying more than 10 entities
* **Configuration changes**: Security settings, integration credentials, RBAC policies
* **Privileged access**: PAM elevation requests, role assignments
* **Data export**: Bulk data exports, audit log downloads
* **Administrative actions**: User management, organization settings
## Service Architecture
CaseBender is composed of isolated microservices, each with a single responsibility:
### Service Inventory
| Service | Purpose | Exposed Ports | External Access |
| ---------------------- | --------------------------------------------------- | ------------- | ----------------------- |
| **web** | Next.js application server, UI, and tRPC API | 3000 | Yes (via reverse proxy) |
| **api** | RESTful API for external integrations | 4000 | Yes (via reverse proxy) |
| **worker** | Background job processing (alerts, enrichment, SLA) | None | No |
| **ingestion** | Alert ingestion from external sources | 4100 | Yes (via reverse proxy) |
| **workflow-processor** | Playbook and workflow execution | None | No |
| **misp-processor** | MISP threat intelligence processing | None | No |
| **search-sync** | Elasticsearch synchronization | None | No |
### Service Isolation
* Each service runs in its own container with a dedicated non-root user
* Services that do not need external access have no exposed ports
* Inter-service communication uses authenticated internal channels
* Each service has its own resource limits (CPU, memory)
* Container images use minimal Alpine Linux base images to reduce attack surface
## Network Security
### Segmentation
CaseBender's network architecture separates concerns into distinct zones:
* **Public Zone**: Reverse proxy / load balancer (the only externally accessible component)
* **Application Zone**: Web, API, and ingestion services (accessible only from public zone)
* **Processing Zone**: Worker, workflow-processor, misp-processor, search-sync (no external access)
* **Data Zone**: PostgreSQL, Redis, Elasticsearch (accessible only from application and processing zones)
### Communication Security
* All external traffic requires TLS 1.3 (TLS 1.2 minimum with strong cipher suites)
* Inter-service communication uses mutual TLS or HMAC authentication
* Database connections are encrypted with SSL certificates
* Redis connections use AUTH and TLS
* Elasticsearch connections use API key authentication over TLS
### Rate Limiting
CaseBender implements multi-layer rate limiting:
* **Global**: Protects the entire platform from volumetric attacks
* **Per-API-Key**: Tier-based limits (Standard, Professional, Enterprise)
* **Per-Endpoint**: Sensitive endpoints (login, password reset) have stricter limits
* **Sliding Window**: Prevents burst attacks while allowing legitimate traffic patterns
## Multi-Tenant Security
### Tenant Isolation
CaseBender supports multi-tenant deployments with strict data isolation:
* **Database-Level**: Every query is scoped to the tenant's `organizationId` — there is no way to query across tenants
* **Application-Level**: Middleware enforces tenant context on every request before it reaches business logic
* **API-Level**: API keys are scoped to a specific tenant and cannot access other tenants' data
* **Search-Level**: Elasticsearch indices are tenant-scoped with filtered aliases
### TLP Classification
The Traffic Light Protocol (TLP) provides an additional layer of data access control:
| TLP Level | Visibility | Use Case |
| -------------------- | ------------------------------------- | --------------------------------------------------- |
| **TLP:RED** | Named recipients only | Active incident details, threat actor attribution |
| **TLP:AMBER+STRICT** | Organization only, restricted sharing | Vulnerability details, internal investigation notes |
| **TLP:AMBER** | Organization and clients | Threat intelligence, remediation guidance |
| **TLP:GREEN** | Community-wide | General security advisories, best practices |
| **TLP:CLEAR** | Unrestricted | Public information, published CVEs |
TLP classifications propagate automatically from cases to child entities (alerts, tasks, observables) and are enforced at the query level.
## Container Security
### Build-Time Hardening
Every CaseBender container image follows security best practices:
* **Multi-Stage Builds**: Build dependencies are not included in production images
* **Non-Root Users**: All services run as dedicated non-root users
* **Minimal Base Images**: Alpine Linux to minimize attack surface
* **Pinned Dependencies**: All system packages and tools are version-pinned
* **Frozen Lockfiles**: `pnpm install --frozen-lockfile` ensures reproducible builds
* **No Secrets in Images**: All secrets are injected at runtime via environment variables or secrets providers
### Runtime Hardening
* Read-only root filesystem (where supported)
* Dropped Linux capabilities
* Resource limits (CPU, memory, file descriptors)
* Health check endpoints for orchestrator monitoring
* Graceful shutdown handling for zero-downtime deployments
## Related Documentation
* [Data Protection](/en/security/data-protection) — Encryption, classification, and secrets management
* [Authentication](/en/security/authentication) — MFA, SSO, and session management
* [Supply Chain Security](/en/security/supply-chain) — Container signing and build verification
* [Hardening Guide](/en/security/hardening-guide) — Deployment hardening recommendations
# Authentication
Source: https://docs.casebender.com/en/security/authentication
Multi-factor authentication, SSO, account lockout, and step-up authentication in CaseBender.
## Multi-Factor Authentication
CaseBender supports multiple MFA methods to protect user accounts. MFA can be enforced at the organization level, ensuring all users comply with your security policy.
### TOTP (Time-Based One-Time Password)
Standard TOTP authentication compatible with all major authenticator apps:
* **Google Authenticator**
* **Microsoft Authenticator**
* **Authy**
* **1Password**
* Any TOTP-compatible app (RFC 6238)
Setup process:
1. User navigates to Security Settings
2. Scans QR code with their authenticator app
3. Enters a verification code to confirm enrollment
4. Backup codes are generated for account recovery
### WebAuthn / FIDO2 Hardware Tokens
For organizations requiring phishing-resistant authentication:
* **YubiKey** (USB-A, USB-C, NFC)
* **Google Titan** Security Keys
* **Windows Hello** (biometric)
* **Apple Touch ID / Face ID** (platform authenticators)
* Any FIDO2-compliant authenticator
WebAuthn provides the strongest authentication because:
* Credentials are bound to the origin (phishing-resistant)
* Private keys never leave the hardware token
* No shared secrets that can be intercepted
* Supports user verification (PIN or biometric)
### Backup Codes
When enrolling in MFA, users receive one-time backup codes for account recovery:
* 10 single-use codes generated at enrollment
* Each code can only be used once
* Codes are hashed before storage (cannot be retrieved, only verified)
* New codes can be regenerated (invalidates all previous codes)
## Single Sign-On (SSO)
### SAML 2.0
CaseBender supports SAML 2.0 for enterprise SSO integration:
* **Identity Providers**: Okta, Azure AD, OneLogin, PingFederate, ADFS, and any SAML 2.0 compliant IdP
* **SP-Initiated SSO**: Users start at CaseBender and are redirected to the IdP
* **IdP-Initiated SSO**: Users start at the IdP portal and are directed to CaseBender
* **Single Logout (SLO)**: Logging out of CaseBender terminates the IdP session
* **Attribute Mapping**: Map IdP attributes to CaseBender user fields (name, email, role, team)
### SCIM Provisioning
Automate user lifecycle management with SCIM 2.0:
* **User Provisioning**: Automatically create CaseBender accounts when users are added in your IdP
* **User Deprovisioning**: Automatically disable accounts when users are removed from the IdP
* **Group Sync**: Map IdP groups to CaseBender teams and roles
* **Profile Updates**: Changes in the IdP (name, email, department) sync to CaseBender automatically
### Just-In-Time (JIT) Provisioning
For organizations that prefer not to use SCIM:
* Users are automatically created on first SSO login
* Default role and team assignments are configurable
* Attribute mapping determines initial permissions
* Administrators can review and adjust JIT-provisioned accounts
## Account Lockout
CaseBender implements progressive account lockout to prevent brute-force attacks:
### Lockout Policy
| Attempt | Action |
| ------- | ---------------------------------------- |
| 1-4 | Normal login flow |
| 5 | Account locked for 5 minutes |
| 6-9 | Extended lockout with progressive delays |
| 10+ | Account locked until admin intervention |
### Lockout Features
* **Progressive Delays**: Each subsequent lockout increases the wait time
* **IP-Based Tracking**: Failed attempts are tracked per IP address in addition to per account
* **Admin Unlock**: Administrators can manually unlock accounts
* **Notification**: Users and administrators are notified of lockout events
* **Audit Trail**: All lockout events are logged with IP address, user agent, and timestamp
## Step-Up Authentication
Even with a valid session, CaseBender requires re-authentication for sensitive operations:
### Operations Requiring Step-Up
* Changing security settings (MFA, SSO configuration)
* Modifying RBAC policies or role assignments
* Bulk delete operations (cases, alerts, tasks)
* Exporting audit logs or sensitive data
* Privileged access elevation (PAM)
* Changing integration credentials
* Modifying data retention policies
### Step-Up Methods
Users can satisfy step-up requirements using any enrolled MFA method:
* TOTP code from authenticator app
* WebAuthn/FIDO2 hardware token tap
* Backup code (one-time use)
Step-up sessions have a configurable expiry (default: 15 minutes) after which re-authentication is required again.
## Session Management
* **Configurable Session Duration**: Organizations can set session timeout policies
* **Concurrent Session Limits**: Configurable maximum concurrent sessions per user
* **Session Revocation**: Administrators can terminate any user's active sessions
* **Idle Timeout**: Sessions expire after configurable inactivity period
* **Secure Cookies**: HTTP-only, Secure, SameSite=Strict cookie attributes
## Related Documentation
* [Session lifetime policy](/en/settings/authentication/session-lifetime) — Configure idle and absolute session limits
* [Access Control](/en/security/access-control) — RBAC, PAM, and API security
* [Security Architecture](/en/security/architecture) — Zero Trust design principles
* [Audit Logging](/en/security/audit-logging) — Authentication event logging
# Data Protection
Source: https://docs.casebender.com/en/security/data-protection
How CaseBender protects your data with encryption, classification, secrets management, and retention policies.
## Encryption
### Data at Rest
All data stored by CaseBender is encrypted at rest:
* **Database**: PostgreSQL Transparent Data Encryption (TDE) or filesystem-level encryption (dm-crypt/LUKS)
* **Field-Level Encryption**: Sensitive fields (API keys, integration credentials, PII) are encrypted at the application level using AES-256-GCM before storage
* **Key Versioning**: Encryption keys are versioned, allowing rotation without re-encrypting all data immediately
* **Backup Encryption**: Database backups inherit encryption from the underlying storage
### Data in Transit
All network communication is encrypted:
* **External Traffic**: TLS 1.3 required (TLS 1.2 minimum with AEAD cipher suites only)
* **Inter-Service**: Mutual TLS or HMAC-authenticated channels
* **Database Connections**: SSL/TLS with certificate verification
* **Redis Connections**: TLS with AUTH
* **Elasticsearch**: API key authentication over TLS
### Encryption Key Rotation
CaseBender supports automated encryption key rotation without downtime:
* New key versions are created and activated automatically on schedule
* Existing data continues to decrypt with the previous key version
* Background re-encryption progressively migrates data to the new key
* Progress tracking shows re-encryption status across all encrypted fields
* Old key versions are retained until all data is migrated, then securely destroyed
## Data Classification
CaseBender includes an automatic data classification engine that categorizes data based on sensitivity:
### Classification Levels
| Level | Description | Handling Requirements |
| ---------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| **Restricted** | Highly sensitive data (credentials, PII, threat actor attribution) | Field-level encryption, strict access control, audit logging on every access |
| **Confidential** | Internal security data (case details, investigation notes) | Encrypted storage, role-based access, audit logging |
| **Internal** | Operational data (metrics, team assignments, workflow configs) | Standard access controls, periodic review |
| **Public** | Non-sensitive data (published CVEs, public advisories) | No special handling required |
### Automatic Classification
* **Rule Engine**: Configurable rules that classify entities based on content patterns, source, severity, and TLP level
* **Pattern Detection**: Scans for PII patterns (SSN, credit card numbers, email addresses) and auto-classifies accordingly
* **TLP Mapping**: TLP classifications automatically map to data classification levels
* **Propagation**: Classification levels propagate from parent to child entities (case to alerts, alerts to observables)
* **Review Workflow**: Classification changes above a threshold require human review and approval
## Secrets Management
CaseBender provides a centralized secrets management system with provider abstraction, so your deployment can use whichever secrets backend your organization standardizes on.
### Supported Providers
| Provider | Use Case | Features |
| ------------------------- | ------------------------------- | ------------------------------------------------ |
| **Environment Variables** | Development, simple deployments | Zero dependencies, easy setup |
| **HashiCorp Vault** | Enterprise on-premise | Dynamic secrets, lease management, audit logging |
| **AWS Secrets Manager** | AWS deployments | Automatic rotation, cross-region replication |
| **Azure Key Vault** | Azure deployments | HSM-backed keys, managed identity integration |
| **GCP Secret Manager** | Google Cloud deployments | IAM integration, automatic replication |
| **Kubernetes Secrets** | Kubernetes deployments | Native K8s integration, RBAC-controlled |
### Secrets Security Features
* **Audit Logging**: Every secret access, creation, update, and deletion is logged with actor identity and timestamp
* **Rotation Scheduling**: Automated rotation policies with configurable intervals per secret
* **Circuit Breaker**: If a secrets provider becomes unavailable, the system gracefully degrades with cached values and alerts operators
* **Retry with Backoff**: Transient failures are retried with exponential backoff before triggering the circuit breaker
* **Health Monitoring**: Continuous health checks on secrets providers with alerting on degradation
## Data Retention
CaseBender supports configurable data retention policies that comply with multiple regulatory frameworks:
### Jurisdiction-Aware Retention
Retention policies are configurable per jurisdiction to meet local regulatory requirements:
| Framework | Minimum Retention | Right to Erasure | Legal Basis Required |
| ------------------ | ------------------------------- | ---------------- | -------------------- |
| **GDPR** | No minimum (purpose limitation) | Yes (Article 17) | Yes |
| **SOC2** | 1 year | No | No |
| **HIPAA** | 6 years | No | No |
| **PCI DSS** | 1 year | No | No |
| **SEC Rule 17a-4** | 3-7 years | No | No |
| **CMMC** | 3 years | No | No |
### Retention Features
* **Policy Engine**: Define retention periods by entity type, classification level, and jurisdiction
* **Legal Hold Integration**: Entities under legal hold are exempt from automated deletion regardless of retention policy
* **Erasure Requests**: GDPR-compliant right to erasure with verification and audit trail
* **Impact Preview**: Before executing retention, preview exactly which entities will be affected
* **Automated Execution**: Scheduled retention jobs with full audit logging of every deletion
## Related Documentation
* [Security Architecture](/en/security/architecture) — Zero Trust design and service isolation
* [Authentication](/en/security/authentication) — How access to data is controlled
* [Compliance: GDPR](/en/security/compliance-gdpr) — GDPR-specific data protection features
* [Audit Logging](/en/security/audit-logging) — How data access is tracked
# Security Overview
Source: https://docs.casebender.com/en/security/overview
CaseBender is built for security teams and secured like one. Explore our enterprise-grade security controls, compliance frameworks, and transparent build pipeline.
## Built for Security Teams, Secured Like One
CaseBender is an on-premise case management platform purpose-built for Security Operations Centers. We understand that the tools security teams rely on must meet the same rigorous standards they enforce across their organizations.
### Pipeline Workflows
Every code change to CaseBender passes through automated checks before it reaches a release:
| Workflow | What It Covers |
| -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Security Scan](https://github.com/casebender/webapp/actions/workflows/security-scan.yml) | Gitleaks, Trivy, Semgrep SAST, ESLint Security, OWASP ZAP, dependency review, license compliance, SBOM generation |
| [Supply Chain Verify](https://github.com/casebender/webapp/actions/workflows/supply-chain-verify.yml) | Reproducible build verification, lockfile integrity, and dependency controls |
| [Main Image Build](https://github.com/casebender/webapp/actions/workflows/build-all-images-publish-deploy.yml) | Hadolint, Trivy, Docker Scout, BuildKit SBOM/provenance, digest signing, SHA tags, and the `edge` channel |
| [On-Premises Release](https://github.com/casebender/webapp/actions/workflows/release-onprem.yml) | Complete-set SemVer promotion, stable aliases, an image-digest manifest inside the signed source-free bundle, and verified Vercel Blob publication |
| [Accessibility Audit](https://github.com/casebender/webapp/actions/workflows/accessibility-audit.yml) | Automated WCAG 2.1 AA, Section 508, and ADA-oriented checks |
The source repository is private. GitHub intentionally returns `404 Not Found` for workflow badge image requests that do not include an authorized GitHub session, including images embedded from this public documentation site. Authorized reviewers can open the workflow links above; other customers can use the release-specific evidence described in the [Security Evidence Guide](/en/security/security-evidence).
## Security by the Numbers
From Zero Trust architecture to DDoS protection, covering SEC-001 through SEC-020
SOC2, ISO 27001, GDPR, CMMC, FedRAMP, HIPAA, PCI DSS, and more
Automated scanning on every commit: SAST, DAST, SCA, secrets, licenses, containers
Your data never leaves your infrastructure. No telemetry, no cloud dependencies
Release workflows use Sigstore signatures and signed provenance for supported publication channels
Each service image is individually built and scanned; signing workflows operate on immutable digests
## Security Principles
### Defense in Depth
CaseBender implements multiple layers of security controls. No single control is relied upon in isolation:
* **Perimeter**: Rate limiting, DDoS detection, input validation, SSRF prevention
* **Authentication**: MFA (TOTP + WebAuthn/FIDO2), SSO (SAML 2.0), step-up authentication
* **Authorization**: RBAC, TLP-based access control, privileged access management
* **Data**: Encryption at rest (AES-256) and in transit (TLS 1.3), field-level encryption, data classification
* **Monitoring**: UEBA behavioral analytics, insider threat detection, unified audit trail, SIEM forwarding
* **Supply Chain**: Signed images, SBOM, SLSA provenance, dependency scanning, reproducible builds
### Zero Trust Architecture
Every request is verified regardless of origin. CaseBender implements:
* Device trust assessment with risk scoring
* Mutual service authentication (HMAC) between microservices
* Step-up authentication for sensitive operations
* Continuous session validation
* No implicit trust between services
### On-Premise Advantage
As an on-premise platform, CaseBender provides inherent security benefits:
* **Data Sovereignty**: Customer data stays within your infrastructure boundary
* **Network Control**: You control all ingress and egress
* **Air-Gap Support**: Deployable in fully isolated environments
* **No Vendor Access**: CaseBender has zero access to your running instance or data
* **Compliance Simplification**: Your data classification and retention policies apply directly
## Explore Security Documentation
Merge-blocking controls, release assurance, evidence, limitations, and customer responsibilities
Zero Trust design, service mesh, network segmentation, and multi-tenant isolation
Encryption, data classification, TLP system, secrets management, and retention policies
MFA, SSO, account lockout, step-up authentication, and WebAuthn/FIDO2
RBAC, privileged access management, cross-team visibility, and API security
UEBA, insider threat detection, DDoS protection, and SIEM integration
SOC2, ISO 27001, GDPR, CMMC, FedRAMP, HIPAA, PCI DSS, and more
Dependency management, container signing, SBOM, SLSA provenance
SAST, DAST, vulnerability management, penetration testing, license compliance
Scanner reports, SBOMs, signatures, provenance, exceptions, and evidence interpretation
Unified audit trail, integrity verification, legal hold, e-discovery
Deployment hardening, database security, container security, monitoring
## Responsible Disclosure
If you discover a security vulnerability in CaseBender, please report it responsibly to [security@casebender.com](mailto:security@casebender.com). We take all reports seriously and will respond within 24 hours.
# API Keys
Source: https://docs.casebender.com/en/settings/account/api-keys
Create, scope, monitor, rotate, suspend, revoke, and securely use CaseBender API keys.
## Overview
API keys provide programmatic access to CaseBender. Open **Settings → Account → API Keys** to manage keys available to your account and current organization.
The page provides:
* Search and status or tier filters
* Masked key identifiers
* Status, tier, last-used time, and request count
* Usage statistics
* Lifecycle actions such as rotation, suspension, revocation, and deletion
An API key is a credential. Store it in an approved secrets manager, never commit it to source control, and never include it in logs, screenshots, tickets, or chat messages.
## Prerequisites
* Your role must allow write operations and API-key management.
* Available scopes are filtered according to your role.
* Creating, revoking, or deleting a key can require step-up authentication.
* Your organization can impose additional authentication and access policies.
Read-only roles can view permitted information but cannot mutate keys.
## Create an API key
Go to **Settings → Account → API Keys**.
Select **Create API Key**.
Enter a clear **Name** and optional description identifying the workload, owner, and purpose.
Choose the tier appropriate for the workload's expected request volume. Available tiers range from **Basic** through **Unlimited**.
Optionally enter the number of days until expiration. Prefer short, policy-aligned lifetimes for production credentials.
Choose at least one scope. Use **Select all** only when the workload legitimately requires every scope available to your role.
Select **Create Key** and complete step-up authentication when prompted.
Copy the complete key from **Save Your API Key** into an approved secrets manager before selecting **Done**.
The complete key is displayed only once. CaseBender stores only the information required to validate and identify it; the plaintext credential cannot be retrieved later.
## Choose scopes
Scopes use a resource-and-action pattern, such as `cases:read` or `organizations:*`. Scope categories can include cases, alerts, tasks, users, teams, organizations, settings, and API-key management.
Follow least privilege:
* Use read-only scopes for reporting and search workloads.
* Grant write scopes only when the integration performs mutations.
* Avoid wildcard and administrative scopes for single-purpose integrations.
* Create separate keys for unrelated services or environments.
* Review scope requirements whenever an integration changes.
The Settings creation form and API only allow scopes possessed by the key
manager. A key cannot mint a replacement key with broader permissions, TLP
clearance, or administrative scope. API requests are evaluated against the
key's scopes, fixed organization, owner status, role permissions, team access,
and TLP clearance.
Grant `api-keys:write`, wildcard, or administrative scopes only to trusted automation that is explicitly authorized to create or manage other credentials.
## Choose a tier
The tier records the intended service class for a key. The available tiers are:
* **Basic**
* **Standard**
* **Professional**
* **Enterprise**
* **Unlimited**
Effective request, bulk-operation, and concurrency limits depend on deployment configuration. Validate production throughput and enforcement with your platform administrator rather than assuming that selecting a tier changes the active limits or makes a key unrestricted.
## Authenticate API requests
Use the complete key with one of the supported single-key headers.
### Recommended: Bearer token
```bash theme={null}
curl "https://your-instance.casebender.com/api/v1/alerts" \
--header "Authorization: Bearer $CASEBENDER_API_KEY" \
--header "Content-Type: application/json"
```
### Alternative: X-Api-Key
```bash theme={null}
curl "https://your-instance.casebender.com/api/v1/alerts" \
--header "X-Api-Key: $CASEBENDER_API_KEY" \
--header "Content-Type: application/json"
```
Store the key in an environment variable or secret injection mechanism. Do not paste a real key directly into shell history or source code.
See the [API Reference introduction](/api-reference/introduction) for additional examples.
## Understand key statuses
* **Active** keys can authenticate requests, subject to scope and policy checks.
* **Suspended** keys are temporarily disabled and can be reactivated.
* **Revoked** keys are permanently invalid.
* **Expired** keys have passed their configured expiration.
A key also fails authentication when its owner is disabled, locked, deleted, or
no longer belongs to the key's organization.
## View usage statistics
Open a key's action menu and select **View Stats** to review:
* Total requests
* Successful requests
* Failed requests
* Average response time
* Top endpoints
Use these statistics to identify unused credentials, unexpected endpoints, and workloads that require a different tier.
## Rotate a key
Rotation replaces the current secret with a new one.
Only the key owner or an explicitly authorized administrator in the same
organization can rotate it. Rotation never returns a replacement credential
for another tenant's key.
Confirm that you can update the consuming service immediately and have a rollback plan.
Open the key's action menu and select **Rotate Key**.
Copy the newly displayed credential into your secrets manager.
Update the consuming workload, restart or redeploy it as required, and make a scoped test request.
Rotation invalidates the previous secret. Coordinate the change to avoid an integration outage.
Rotation is operator-initiated. A stored rotation interval does not by itself guarantee that CaseBender will rotate and distribute a replacement key automatically.
## Suspend or reactivate a key
Use **Suspend** to stop a key temporarily during an investigation or planned maintenance. Use **Reactivate** only after confirming that the credential and its consumer are trusted.
Suspension is preferable to deletion when you need a reversible containment action.
## Revoke a key
Use **Revoke** when a credential is compromised, no longer trusted, or permanently retired. Revocation can require step-up authentication and cannot be reversed.
After revocation:
1. Remove the secret from all consumers.
2. Review usage statistics and security telemetry.
3. Investigate unexpected requests.
4. Create a separate replacement key only if the workload remains authorized.
## Delete a key
Deletion removes the key record and its direct management visibility. It can require step-up authentication.
Revoke a key before deleting it when you need a clear credential-retirement sequence. The current action menu does not provide a separate confirmation dialog for every destructive operation.
## Security recommendations
* Assign a named human owner and workload owner.
* Use separate keys for production, staging, and development.
* Set an expiration aligned with your credential policy.
* Rotate immediately after suspected exposure.
* Monitor failed requests and unexpected endpoints.
* Revoke unused keys instead of leaving them active.
* Never send keys through email or collaboration tools.
## Troubleshooting
### Create Key is rejected
Enter a name, select at least one scope, confirm that your role has write access, and complete any step-up authentication challenge.
### An API request returns 401
Confirm that the complete active key is supplied as a Bearer token or `X-Api-Key`, and verify that it has not expired, been suspended, or been revoked.
### An API request returns 403
The key authenticated successfully but lacks the required scope or data access. Add only the minimum required scope through an authorized key-management workflow.
### Requests are rate limited
Reduce request frequency, honor retry guidance from the response, or ask an administrator whether the workload requires another tier.
### The complete key is no longer visible
Plaintext keys cannot be retrieved. Rotate the key or create a replacement and update the consumer.
## API reference
* [List API keys](/api-reference/endpoint/api-keys/list)
* [Create an API key](/api-reference/endpoint/api-keys/create)
* [List available scopes](/api-reference/endpoint/api-keys/scopes)
* [Get an API key](/api-reference/endpoint/api-keys/get-by-id)
* [Rotate an API key](/api-reference/endpoint/api-keys/rotate)
* [View API key statistics](/api-reference/endpoint/api-keys/stats)
* [Delete an API key](/api-reference/endpoint/api-keys/delete)
## Related guides
* [API Reference introduction](/api-reference/introduction)
* [Access Control](/en/security/access-control)
* [Organizations](./organizations.mdx)
# Members
Source: https://docs.casebender.com/en/settings/account/members
Invite, review, and manage CaseBender users, roles, and team assignments.
## Overview
The Members section provides a directory of CaseBender users and the controls available for managing their access. Open **Settings → Account → Members**.
What you can view or change depends on your role and assigned permissions. Administrative controls are available to authorized Super Admins and Organization Admins.
## Find a member
Use the member list to:
* Search by name or email address
* Filter by role
* Review team and role counts
Select **Manage** when you have administrative user-management permission to open the member's detail page.
## Invite a member
Inviting members requires user-invite permission and an administrative role. The server also enforces the licensed seat count. Community includes 1 user; a paid key raises that limit. See [License](/en/settings/license).
Go to **Settings → Account → Members**.
Select **Invite member**.
Provide the email address associated with the new account.
Select an organization and an appropriate role. Team assignment is optional; if selected, the team must belong to the chosen organization. Organization Admins can provision only within their scope, and only a Super Admin can assign the Super Admin role.
Select **Send invitation**, then follow the outcome shown by CaseBender.
### Delivery and activation
CaseBender chooses SMTP in this order: the effective organization-scoped SMTP integration, a visible-to-all SMTP integration, then the legacy or global SMTP configuration.
* With working SMTP, the new account remains **Pending** and receives one single-use acceptance link that expires after 72 hours. Accepting the invitation sets the password and activates the account.
* If no valid SMTP configuration exists, CaseBender creates a random, policy-compliant 20-character temporary password, displays it once to the administrator, and requires the member to change it at first sign-in.
* If configured SMTP delivery fails, CaseBender does not silently issue a password. The result screen offers **Retry email** or the explicit **Issue temporary password** fallback.
* If the email belongs to an existing active user, CaseBender assigns the organization, optional team, and role without resetting credentials. A notification is attempted when SMTP is available, but notification failure does not undo the assignment.
## Create an account as Super Admin
Only Super Admins can use **Create account**. Select an organization, an optional team from that organization, and a role. Choose either a server-generated initial password or provide a policy-compliant initial password. **Require password change** is enabled by default and can be changed before creation.
Temporary credentials and invitation tokens are never stored in plaintext. A temporary password is displayed only once; deliver it through an approved secure channel and do not place it in email, chat, tickets, or other unapproved systems.
For enterprise-managed identities, your organization can also provision users through SCIM, Just-In-Time provisioning, and identity-provider group mapping. See [Authentication](/en/security/authentication).
## Review member details
Open a member to review:
* Avatar
* Email address and account status
* Display name
* Team assignments
* Scoped roles
Email addresses are identity attributes and are displayed as read-only on the member detail page.
## Update a member
### Name and avatar
A user can update their own name and avatar. Super Admins and Organization Admins can update these fields for users within their administrative responsibilities.
### Roles
Authorized administrators can change a member's role from the member detail page.
Role changes can immediately alter access to cases, alerts, tasks, settings, and sensitive data. Apply least privilege and verify the scope before saving.
### Team assignments
Use the member detail page or the relevant team page to review team membership and team-scoped roles. Removing a member from a team also removes role assignments scoped to that team.
### Reset a local password
An authorized administrator can issue a new temporary password for a member who authenticates with a local CaseBender password. The password is generated by the server, displayed once to the administrator, and cannot be retrieved afterward. Issuing it requires the member to change the password at the next sign-in and invalidates credentials from existing sessions.
Share a temporary password only through an approved secure channel. Do not copy it into email, chat, tickets, or other systems that are not approved for credential delivery.
Identity-provider-managed users are different: reset their password and recover their account through the IdP. CaseBender does not replace an SSO, LDAP, or other externally managed password with a local temporary password.
## Remove a member
Member removal requires user-delete permission and an administrative role. The interface prevents most administrators from deleting their own account.
Before removing a member:
1. Reassign active cases, alerts, and tasks.
2. Revoke or replace credentials and integrations that depend on the member.
3. Preserve records required by retention or legal-hold policies.
4. Confirm that automated identity provisioning will not recreate the account unexpectedly.
The member-list delete action does not provide a separate confirmation dialog. Verify the selected member before invoking it.
## Access and permissions
* All authenticated users can open the Members section.
* Invite and delete actions require explicit user-management permissions.
* Role changes require administrative role-management permission.
* Users can edit their own supported profile fields.
* The server validates each mutation independently of the controls shown in the interface.
For role definitions and scoped authorization, see [Access Control](/en/security/access-control).
## Provisioning strategies
### Manual administration
Use the Members interface for individually managed accounts and targeted role or team changes.
### SCIM
Use SCIM when your identity provider should control account creation, profile synchronization, and deprovisioning.
### Just-In-Time provisioning
Use JIT provisioning to create approved users when they first authenticate through SSO.
### Group synchronization
Map identity-provider groups to CaseBender organizations, teams, and roles for repeatable access assignment.
Choose one authoritative lifecycle for each user population. Mixing manual assignments with automated group synchronization can cause a later synchronization to replace an administrator's change.
## Operational recommendations
* Review pending and elevated accounts regularly.
* Remove access promptly when responsibilities change.
* Avoid granting administrative roles as a convenience.
* Verify organization and team scope after every role change.
* Use your identity provider as the source of truth when automated provisioning is enabled.
## Troubleshooting
### I do not see Invite member
You need an administrative role and user-invite permission.
### The invitation email was not delivered
Use **Retry email** after correcting SMTP, or explicitly choose **Issue temporary password** and share the one-time credential through an approved secure channel. If no SMTP configuration is valid, the temporary-password outcome is shown automatically.
### No teams are available
Team assignment is optional. If you select a team, it must belong to the selected organization and be within your administrative scope.
### I do not see Create account
The direct **Create account** flow is available only to Super Admins.
### A role change is rejected
Confirm that your role can manage users and that any required step-up authentication has been completed.
### Password reset is unavailable
Confirm that the member uses local password authentication and that you have administrative access within the member's organization. For an identity-provider-managed member, perform the reset in the IdP.
### A member reappeared after removal
SCIM, JIT, or group synchronization might still assign the user. Update the identity-provider configuration before repeating the removal.
### I can view a member but cannot edit them
Directory visibility does not grant user-management permission. Contact an appropriate administrator.
## API access
Related scope-controlled user endpoints include:
* [List users](/api-reference/endpoint/users/list)
* [Get the current user](/api-reference/endpoint/users/me)
* [Get a user](/api-reference/endpoint/users/get-by-id)
* [Update a user](/api-reference/endpoint/users/update)
## Related guides
* [Profile](./profile.mdx)
* [Teams](./teams.mdx)
* [Organizations](./organizations.mdx)
* [License](/en/settings/license)
* [Access Control](/en/security/access-control)
# Notifications
Source: https://docs.casebender.com/en/settings/account/notifications
Review your notification inbox and configure personal channel, event, and Do Not Disturb preferences.
## Overview
Open **Settings → Account → Notifications** to review your personal notification history and preferences.
The page has two tabs:
* **Inbox** contains notifications addressed to your account.
* **Preferences** contains personal channel, event, and Do Not Disturb settings.
Team delivery destinations are configured separately from the **Notifications** tab on each team.
## Use the Inbox
### Filter notifications
Select:
* **All notifications** to show read and unread items
* **Unread only** to focus on items that still require review
* **Action required** to show critical or assigned work that needs explicit acknowledgement
The page loads notifications in batches. Select **Load more** when additional history is available.
### Open the related record
When a notification references a case, alert, or task, select its entity link to open that record.
Your normal role, team, organization, and TLP permissions still apply. Receiving a notification does not grant access to the referenced record.
### Mark notifications as read
* Select **Mark read** for an individual notification.
* Select **Mark all read** to update all unread notifications in your inbox.
Reading an item does not acknowledge it. For an item marked **Action required**, select **Acknowledge** after accepting responsibility for the response.
### Archive notification history
Archive an individual item from its action menu, or select **Clear all** to remove all items from the active inbox.
Archiving does not destroy delivery or acknowledgement history. CaseBender retains lifecycle records according to the organization's audit and retention policy.
Archiving an inbox item does not delete the related case, alert, task, or activity.
## Alert and case navigation badges
The **Alerts** and **Cases** badges show the exact number of records created since you last opened the corresponding list. Counts are stored per user and organization, survive refreshes and sign-in sessions, and include only records you are authorized to access.
Opening the alert list advances only the alert cursor. Opening the case list advances only the case cursor.
## Toast policy
CaseBender shows an interruptive toast only for a newly delivered **Critical case** notification (severity 4). Alert creation and non-critical case creation update durable badges and inbox state without producing toast noise. Replayed or historical notifications do not produce toast storms after reconnecting.
## Configure notification channels
Open the **Preferences** tab and use **Notification Channels** to configure:
* **In-app notifications** in the CaseBender notification center
* **Email notifications** through your configured account email
Email delivery also depends on the CaseBender instance having a working outbound email configuration.
Channel preferences express how you want to receive notifications. Delivery can also depend on the event producer, system configuration, and destination availability.
## Configure personal events
The **Personal Notifications** section includes controls for:
* Items assigned to you
* Mentions in comments
* Replies to your comments
* Updates to cases assigned to you
* Task due reminders
Enable only the events that help you act on assigned work without creating unnecessary noise.
## Configure Do Not Disturb
The **Do Not Disturb** section stores your preferred quiet-hour schedule.
You can configure:
* Whether Do Not Disturb is enabled
* Start hour
* End hour
* Weekend inclusion
* Whether critical alerts can override the schedule
Do Not Disturb must not be used as the sole control for paging, on-call coverage, or critical-incident escalation. Confirm critical delivery behavior through your organization's approved alerting channels.
## Personal versus team notifications
Personal preferences apply to notifications addressed to your user account.
Team notification settings control shared destinations such as:
* Slack workspaces and channels
* Slack incoming webhooks
* Microsoft Teams webhooks
* Team email
* Team-level case, alert, task, SLA, and escalation events
To configure a shared destination, go to **Settings → Account → Teams**, open a team, and select **Notifications**. You need team-management permission.
## Access and data isolation
* Every authenticated user can open their own notification page.
* Notification queries and inbox actions are scoped to the signed-in user.
* You cannot read, acknowledge, archive, or clear another user's notifications.
* Read-only roles can be restricted from preference-changing operations.
* Access to linked records is evaluated separately.
## Operational recommendations
### Reduce noise deliberately
* Keep assignment and mention notifications enabled for active responders.
* Disable low-value events instead of ignoring the entire inbox.
* Review preferences after changing teams or responsibilities.
### Protect critical coverage
* Allow critical overrides when required by policy.
* Use team channels for shared operational coverage.
* Test email and collaboration integrations after configuration changes.
### Maintain the inbox
* Mark items read after review.
* Acknowledge actionable items separately from marking them read.
* Follow the entity link before archiving an important notification.
* Treat the inbox as a durable operational record governed by retention policy.
## Troubleshooting
### Email notifications are not arriving
Confirm that email notifications are enabled, verify your account email, and ask an administrator to check the outbound email integration.
### A linked record is inaccessible
The notification does not bypass authorization. Request the appropriate organization, team, role, or TLP access.
### My preference change is rejected
Your role can be read-only or your session might have expired. Sign in again or contact an administrator.
### A team channel is not receiving events
Open the team's **Notifications** tab and verify both the destination and the relevant event controls. Team configuration is independent of this personal page.
## Related guides
* [Teams](./teams.mdx)
* [Profile](./profile.mdx)
* [Access Control](/en/security/access-control)
# Organizations
Source: https://docs.casebender.com/en/settings/account/organizations
Create and govern CaseBender organizations, including hierarchy, TLP, retention, and administrator settings.
## Overview
Organizations define administrative and data-governance boundaries in CaseBender. Open **Settings → Account → Organizations** to view the organizations available to your role.
* **Super Admins** can view all organizations and create new ones.
* **Organization Admins** manage their current organization through the **Organization** item.
* Other roles do not receive organization-management controls unless their permissions explicitly allow them.
For the broader authorization model, see [Access Control](/en/security/access-control).
## Organization structure
An organization can represent a root organization, business unit, department, or team group. Organizations can also be assigned a parent to create a hierarchy.
Organization names must be unique across the CaseBender instance, not only within the same parent organization.
## Create an organization
The Settings interface presents organization creation to Super Admins. The operation also requires an administrative server session.
Go to **Settings → Account → Organizations**.
Select **Create organization**.
Provide a unique name with between 2 and 100 characters.
Submit the form. Open **Manage** from the organization list to configure additional details and governance settings.
## Manage organization details
Select **Manage** for an organization to open its detail page. The available fields are organized into three tabs.
### Basic Info
Use this tab to manage:
* Name and description
* Organization type
* Parent organization
* Contact email
* Time zone
Advanced hierarchy and contact fields are limited to Super Admins. Organization Admins can update fields permitted for their current organization.
### Governance
Governance settings establish defaults and constraints for data handled by the organization.
#### TLP defaults
* **Default TLP** is applied when a workflow does not provide another value.
* **Maximum TLP** limits the highest Traffic Light Protocol level available to the organization.
Choose values that match your data-sharing policy. For details about TLP-aware authorization, see [Access Control](/en/security/access-control).
#### Retention and jurisdiction
Configure:
* Data retention period in days
* Jurisdiction
* Data-classification settings
* Export-controlled status
The default retention period for a newly modeled organization is 1,095 days unless your deployment or administrator establishes another value.
Governance changes can affect data handling across an organization. Review retention, jurisdiction, TLP, and export-control values with the appropriate security, privacy, and legal owners before saving.
### Administrators
The **Administrators** tab separates active and pending Organization Admins. Authorized administrators can use the invitation form to add an Organization Admin.
Role assignment controls who can modify organization, team, and member settings. Apply least privilege and review elevated assignments regularly.
## Deactivate an organization
The organization list prevents a deactivation request when the organization still contains teams or users. Move or remove those dependencies before attempting the action.
Deactivated organizations remain identifiable with a **Deactivated** status because organization removal uses a recoverable lifecycle state rather than immediately erasing the record.
Do not rely on the destructive control shown on an organization's detail page. Use the supported action from the organization list and verify that all dependent teams and users have been handled.
## Access model
* Super Admins have platform-wide organization visibility.
* Organization Admins are presented with their current organization.
* Organization management and data access are separate concerns.
* TLP and scoped roles can further limit which records a user can access.
* The server remains the enforcement point even when the interface hides unavailable actions.
## Operational recommendations
### Design the hierarchy first
* Use stable organizational boundaries.
* Avoid unnecessary hierarchy depth.
* Assign a parent only after confirming the intended reporting and governance relationship.
### Protect governance settings
* Document the owner of each retention and classification decision.
* Treat export-control changes as privileged operations.
* Review default and maximum TLP values after reorganizations.
### Review administrators
* Maintain at least one accountable administrator for every active organization.
* Remove elevated access promptly when responsibilities change.
* Verify pending assignments during periodic access reviews.
## Troubleshooting
### I do not see Create organization
Only a Super Admin can create an organization. Organization Admins manage their assigned organization.
### The organization name is rejected
Use at least two characters and choose a name that is not already used anywhere in the instance.
### I cannot deactivate an organization
Confirm that it no longer contains teams or users. If the interface still blocks the action, contact a Super Admin.
### I cannot edit an advanced field
Organization type, hierarchy, and selected contact settings require Super Admin access.
## API access
Organizations can also be managed through scope-controlled API endpoints:
* [List organizations](/api-reference/endpoint/organizations/list)
* [Get an organization](/api-reference/endpoint/organizations/get-by-id)
* [Create an organization](/api-reference/endpoint/organizations/create)
* [Update an organization](/api-reference/endpoint/organizations/update)
* [View the hierarchy](/api-reference/endpoint/organizations/hierarchy)
## Related guides
* [Teams](./teams.mdx)
* [Members](./members.mdx)
* [Access Control](/en/security/access-control)
# Profile
Source: https://docs.casebender.com/en/settings/account/profile
Manage your identity, avatar, password, and multi-factor authentication settings in CaseBender.
## Overview
Your profile contains the identity and authentication settings associated with your CaseBender account. Open **Settings**, expand **Account**, and select **Profile** to manage these settings.
The options available on this page depend on how you authenticate. Accounts managed by an external identity provider might not display local password controls.
## Update your avatar
Open **Settings**, expand **Account**, and select **Profile**.
Select your current avatar and choose an image from your device.
Wait for the upload to complete. The new avatar is applied to your active session and other places where your identity is displayed.
If an avatar upload does not complete, retry with a supported image file or contact your CaseBender administrator.
## Change your display name
The **Display name** section controls the name shown to other users.
Enter a **First name** and **Last name**. Each value must contain at least two characters.
Select **Save**. CaseBender updates the name in your active session after the change succeeds.
## Change your password
The **Password** section is available only to accounts that use a local CaseBender password. For accounts managed through SSO or another external identity provider, change your password through that provider.
Manually provisioned accounts with **Require password change** enabled are redirected to change the temporary password before normal CaseBender access.
Enter the password you currently use to sign in.
Enter and confirm a password that contains:
* At least eight characters
* At least one lowercase letter
* At least one uppercase letter
* At least one number
* At least one special character
Select **Save**. If the current password is incorrect or the new values do not match, correct the highlighted field and try again.
Never reuse a password from another service. If your organization uses SSO, follow its identity-provider password policy instead.
## Configure multi-factor authentication
The profile page provides controls for supported multi-factor authentication methods:
* **Authenticator app (TOTP)** for time-based verification codes
* **WebAuthn/FIDO2** for compatible security keys and platform authenticators
* **Backup codes** where offered during MFA enrollment
Follow the prompts in the relevant security card to enroll or manage a method. Your organization can require MFA as part of its authentication policy.
For method details and recovery guidance, see [Authentication](/en/security/authentication).
## Access and permissions
* Every authenticated user can open their own profile.
* You can update your own name, avatar, and local password.
* Super Admins and Organization Admins can update selected profile fields for users they administer.
* The server validates authorization even when a control is visible in the interface.
## Troubleshooting
### The Password section is missing
Your account likely authenticates through SSO, LDAP, or another external provider and does not have a local CaseBender password. Use your identity provider to manage the password.
### My current password is rejected
Confirm that you entered the current local password rather than an SSO password. If you cannot recover access, contact your administrator.
### My profile change was not saved
Check the validation message, confirm that your session is still active, and retry. Name fields require at least two characters.
## Security recommendations
* Enroll in the strongest MFA method permitted by your organization.
* Prefer phishing-resistant WebAuthn credentials when available.
* Store backup codes in an approved password manager or secure vault.
* Review unexpected profile changes with your administrator.
## Related guides
* [Authentication](/en/security/authentication)
* [Access Control](/en/security/access-control)
* [Members](./members.mdx)
# Teams
Source: https://docs.casebender.com/en/settings/account/teams
Create and manage CaseBender teams, membership, classification, escalation, and notification channels.
## Overview
Teams organize analysts, ownership, escalation, and notifications within an organization. Open **Settings → Account → Teams**.
The list is scoped according to your role:
* Super Admins can view teams across the instance.
* Organization Admins can view teams in their current organization.
* Other users see teams to which they belong.
## Create a team
Team creation requires an administrative role with team-create permission.
Go to **Settings → Account → Teams**.
Select **Create team**.
Enter a team name and optional description. Team names contain between 2 and 50 characters in the creation form.
A Super Admin selects the organization. An Organization Admin creates the team in their current organization.
Select the team's function and tier. You can also select an escalation team when the team participates in an escalation chain.
Optionally provide an email address, Slack channel, or Microsoft Teams channel reference.
Submit the form, then open the team detail page to manage members and complete notification-channel configuration.
## Manage a team
Select **Manage** or **View** from the team list. The action shown depends on your permissions.
### Basic settings
Administrators with team-management permission can update:
* Name and description
* Team function and tier
* Escalation team
* Email address
* Slack and Microsoft Teams channel references
* Other available team defaults
### Classification
Use function and tier values consistently so routing, reporting, and escalation behavior remain understandable across the SOC.
When assigning an escalation team:
* Confirm that the target team has the required coverage.
* Avoid circular escalation relationships.
* Review escalation ownership after organizational changes.
## Manage members and roles
The team detail page displays active and pending members. Authorized administrators can:
* Invite a member to the team
* Assign or change a team-scoped role
* Remove a member from the team
Role assignments affect the actions a member can perform within the assigned scope. See [Access Control](/en/security/access-control) before granting elevated roles.
## Configure team notifications
Open a team and select the **Notifications** tab. Team notifications are distinct from each user's personal notification preferences.
### Slack
Slack delivery can use:
* An authorized Slack workspace and channel
* A supported incoming webhook configuration
Slack OAuth requires your CaseBender deployment to have the Slack client credentials and public application URL configured. If these prerequisites are missing, contact your platform administrator.
### Microsoft Teams
Provide a supported Microsoft Teams webhook URL and enable the desired event types.
### Email
Email notifications require a valid team email address in the team's **Basic** settings and a configured outbound email integration.
### Event controls
Depending on the configured channel, teams can enable notifications for events involving:
* Cases
* Alerts
* Tasks
* SLA milestones and breaches
* Escalation and collaboration
* Correlation results
Channel settings and event filters are evaluated independently. Enabling an event does not deliver a message unless its destination channel is also configured and enabled.
## Delete a team
Users with team-management permission can delete a team from its detail page.
Team deletion is permanent in the current management flow. Reassign active work, remove integrations that target the team, and preserve any required records before confirming deletion.
After deletion, CaseBender returns to the team list.
## Access and permissions
* All authenticated users can open the Teams section.
* Administrators create, edit, and delete teams according to their role.
* Non-administrators receive a view-only experience for teams in their allowed scope.
* The team detail page displays **Access denied** when a non-Super Admin opens a team outside their current organization.
* Management and notification controls are shown only when the user's role has team-management permission.
## Operational recommendations
### Establish ownership
* Assign a clear function and tier.
* Maintain a monitored team email or collaboration channel.
* Identify a valid escalation team for after-hours or specialist support.
### Control membership
* Grant only the role required for the member's responsibilities.
* Remove stale memberships promptly.
* Review active and pending memberships during access reviews.
### Test notifications
* Validate each destination after changing credentials or webhooks.
* Keep webhook URLs secret.
* Confirm that critical SLA and escalation events reach an attended channel.
## Troubleshooting
### I do not see Create team
Your role does not have team-create permission, or you do not have an organization context in which to create the team.
### I can view but not edit a team
You have read access without team-management permission. Contact an Organization Admin or Super Admin.
### Slack authorization cannot start
Ask a platform administrator to verify the Slack client ID, client secret, and public CaseBender URL.
### Email notifications are not delivered
Confirm that the team has an email address and that outbound email is configured for the instance.
## API access
Scope-controlled team endpoints are available for automation:
* [List teams](/api-reference/endpoint/teams/list)
* [Get a team](/api-reference/endpoint/teams/get-by-id)
* [Create a team](/api-reference/endpoint/teams/create)
* [Update a team](/api-reference/endpoint/teams/update)
* [Add a user](/api-reference/endpoint/teams/add-user)
* [Remove a user](/api-reference/endpoint/teams/remove-user)
## Related guides
* [Organizations](./organizations.mdx)
* [Members](./members.mdx)
* [Notifications](./notifications.mdx)
# AI Settings
Source: https://docs.casebender.com/en/settings/ai/introduction
Configure and manage AI providers to enable intelligent features in your CaseBender instance.
## Overview
The AI Settings section allows you to configure various AI providers to enhance your CaseBender experience with intelligent features. This includes setting up providers like OpenAI, Anthropic, and others to power features such as case analysis, content generation, and automated processing.
## Configuring AI Providers
### Step 1: Enable Provider
To start using an AI provider, locate the provider card in the dashboard and toggle the enable switch:
The configuration modal will appear where you can:
* Enter your API key
* Configure basic settings
* Set usage limits
* Define access permissions
### Step 2: Model Selection
After entering a valid API key, you'll see available models for the provider:
Configure model-specific settings:
* Select preferred models
* Set model-specific parameters
* Configure usage quotas
* Define model access permissions
### Step 3: Provider Configuration Complete
Once configured, the provider card will show its active status and configuration details:
The configured provider card displays:
* Active status
* Selected models
* Usage statistics
* Quick access to settings
## Available Providers
### OpenAI
* GPT-4 and GPT-3.5 models
* Text generation and analysis
* Code assistance
* Data extraction
### Anthropic
* Claude and Claude 2 models
* Advanced reasoning
* Document analysis
* Complex task handling
### Deepseek
* Deepseek-coder models
* Code generation and analysis
* Technical documentation
* Programming assistance
### Azure OpenAI
* Managed OpenAI services
* Enterprise security features
* Regional availability
* Dedicated resources
### Groq
* LPU inference
* Ultra-fast processing
* High-performance models
* Low-latency responses
### Google AI
* PaLM and Gemini models
* Multi-modal capabilities
* Advanced language understanding
* Enterprise-grade reliability
### xAI
* Grok models
* Real-time knowledge integration
* Conversational AI
* Context-aware responses
### Ollama
* Local model deployment
* Custom model support
* Offline processing
* Resource-efficient inference
## Best Practices
### Security
* Securely store API keys
* Regularly rotate credentials
* Monitor API usage
* Set appropriate access controls
### Cost Management
* Configure usage limits
* Monitor token consumption
* Set model-specific quotas
* Track usage patterns
### Performance
* Choose appropriate models
* Optimize prompt engineering
* Monitor response times
* Configure timeout settings
### Maintenance
* Regularly verify provider status
* Update API keys before expiration
* Monitor model availability
* Keep configurations current
## Features Enabled by AI
### Case Management
* Automated case analysis
* Content summarization
* Priority assessment
* Related case identification
### Document Processing
* Text extraction
* Document classification
* Content analysis
* Key information highlighting
### Workflow Automation
* Intelligent routing
* Content generation
* Decision support
* Pattern recognition
## Related Documentation
* [AI Features](../../cases/ai-features.mdx)
# Alert Statuses
Source: https://docs.casebender.com/en/settings/alert-statuses/introduction
Configure and manage custom alert statuses to track the lifecycle of alerts in your security operations.
## Overview
The Alert Statuses section allows you to create and manage custom status definitions for your alerts. This feature helps you track the progression of alerts through your security operations workflow, from initial detection to final resolution.
## Managing Alert Statuses
### Creating a New Status
Click the "Create" button to add a new alert status:
Configure the basic status information:
* Status name
* Description
* Color indicator
* Icon selection
* Category
### Configuring Status Details
Provide comprehensive configuration for your alert status:
Define detailed settings:
* Status behavior
* Automation rules
* Notification settings
* Access permissions
### Status Management
View and manage your configured alert statuses:
The status list displays:
* Status name and icon
* Description
* Category
* Creation date
* Last modified
* Actions
## Default Status Types
### New Alerts
* New
* Unassigned
* Assigned
* In Progress
### Investigation
* Under Investigation
* Needs Information
* Awaiting Response
* On Hold
### Resolution
* Resolved
* Closed
* False Positive
* Duplicate
### Escalation
* Escalated
* Critical
* Requires Attention
* Pending Review
## Status Configuration
### Visual Indicators
* Color coding
* Icon selection
* Status badges
* Priority markers
### Behavior Settings
* Auto-transition rules
* Time-based triggers
* Required fields
* Status dependencies
### Access Control
* Role-based access
* Team permissions
* Status restrictions
* Modification rights
## Best Practices
### Status Design
* Use clear, descriptive names
* Maintain consistent naming
* Choose intuitive colors
* Select appropriate icons
### Workflow Integration
* Define logical progression
* Set up automation rules
* Configure notifications
* Enable tracking
### Organization
* Group related statuses
* Define clear categories
* Set proper ordering
* Maintain hierarchy
### Maintenance
* Review status usage
* Update as needed
* Remove unused statuses
* Document changes
## Using Alert Statuses
### In Alert Management
* Track alert lifecycle
* Monitor progress
* Manage workload
* Measure response time
### In Reporting
* Status distribution
* Resolution metrics
* Team performance
* Response analytics
### In Automation
* Status-based triggers
* Automatic updates
* Notification rules
* Workflow automation
# Attack Patterns
Source: https://docs.casebender.com/en/settings/attack-patterns/introduction
Browse and manage MITRE ATT&CK patterns to enhance your threat detection and response capabilities.
## Overview
The Attack Patterns section provides access to a comprehensive library of MITRE ATT\&CK patterns, enabling you to understand, track, and defend against various cyber attack techniques. This knowledge base helps in identifying, categorizing, and responding to security threats effectively.
## Understanding Attack Patterns
### Pattern Categories
* Initial Access
* Execution
* Persistence
* Privilege Escalation
* Defense Evasion
* Credential Access
* Discovery
* Lateral Movement
* Collection
* Command and Control
* Exfiltration
* Impact
### Pattern Information
Each attack pattern entry includes:
* Technique ID (e.g., T1234)
* Technique Name
* Tactic Category
* Description
* Sub-techniques
* Detection Methods
* Mitigation Strategies
## Using Attack Patterns
### Threat Analysis
* Identify attack techniques
* Map threat actor behaviors
* Analyze attack chains
* Assess risk levels
### Incident Response
* Classify incidents
* Guide investigation
* Determine scope
* Plan remediation
### Threat Hunting
* Create hunt hypotheses
* Define search patterns
* Identify indicators
* Track progression
## Integration Features
### Case Management
* Link patterns to cases
* Document observed techniques
* Track attack progression
* Map incident timeline
### Threat Intelligence
* Correlate with known threats
* Map actor behaviors
* Identify emerging patterns
* Share intelligence
### Reporting
* Generate attack summaries
* Create pattern analytics
* Track pattern frequency
* Measure effectiveness
## Best Practices
### Pattern Analysis
* Review pattern details
* Understand prerequisites
* Identify dependencies
* Map related techniques
### Implementation
* Document observed patterns
* Link to incidents
* Track effectiveness
* Update procedures
### Maintenance
* Keep patterns current
* Review classifications
* Update documentation
* Monitor trends
### Team Training
* Share pattern knowledge
* Practice identification
* Review case studies
* Update procedures
## MITRE ATT\&CK Framework
### Framework Overview
* Enterprise Matrix
* Mobile Matrix
* ICS Matrix
* Cloud Matrix
### Tactics Categories
* Why attackers use them
* Common implementations
* Detection strategies
* Mitigation approaches
### Techniques & Sub-techniques
* Detailed descriptions
* Implementation examples
* Detection methods
* Mitigation strategies
## Related Documentation
* [Case Management](../../cases/introduction.mdx)
# Session lifetime policy
Source: https://docs.casebender.com/en/settings/authentication/session-lifetime
Configure inactivity and absolute session limits for an organization.
## Overview
The session lifetime policy limits how long users can remain signed in. It is
configured separately for each organization and applies to both new and
existing sessions.
You need the **Manage authentication** (`authenticationManage`) permission to
view or change this policy. Platform authentication providers remain restricted
to platform Super Admins.
## Configure session limits
Go to **Settings → Authentication** and find **Session Lifetime Policy** in
the Security Policy card.
Platform Super Admins can select an organization. Other authorized
administrators can manage only their current organization.
Enter the maximum period of inactivity before CaseBender requires the user
to sign in again. The allowed range is **5–1,440 minutes**. The default is
**30 minutes**.
Enter the maximum total age of a session, even while the user remains
active. The allowed range is **60–10,080 minutes**. The default is
**480 minutes (8 hours)**.
The absolute lifetime must be greater than or equal to the idle timeout.
Changes are saved when you leave the field.
## How enforcement works
* Activity refreshes the idle timer but never extends the absolute lifetime.
* CaseBender evaluates protected page and API requests against the current
organization policy.
* A policy reduction also applies to sessions that were created before the
change.
* When either limit is reached, the server revokes the session and requires a
new sign-in.
* Policy updates can take up to 60 seconds to propagate to every application
process.
A page already displayed in a browser does not disappear at the exact timeout
instant if it makes no server requests. The next protected navigation, data
refresh, or action is rejected and requires sign-in.
## Recommended starting points
* Use a shorter idle timeout for privileged or shared-workstation users.
* Keep the absolute lifetime within a normal work shift unless your security
policy requires a shorter period.
* Test policy reductions with a non-production account before applying them to
a large organization.
* Coordinate these limits with your identity provider's own session and
single-sign-on policies. The shortest effective limit can require the user to
authenticate again.
## Troubleshooting
### The policy controls are not visible
Confirm that your effective role includes `authenticationManage` and that you
are using an internal account. External collaborators cannot access
Authentication settings.
### Users remain on an open page after the timeout
This does not mean the server session is still valid. Ask the user to navigate
or refresh. The next protected request triggers session validation.
### A value cannot be saved
Confirm that the idle timeout and absolute lifetime are within their supported
ranges and that the absolute lifetime is not shorter than the idle timeout.
## Related documentation
* [Authentication and MFA](/en/security/authentication)
* [Access control](/en/security/access-control)
* [Activity logs](/en/audits/activity-logs)
# Branding
Source: https://docs.casebender.com/en/settings/branding/introduction
Customize the look and feel of your CaseBender instance with your organization's branding elements.
## Overview
The Branding section allows you to customize the visual appearance of your CaseBender instance to match your organization's brand identity. You can configure colors, logos, and other visual elements to create a consistent and professional look across your security operations platform.
## Brand Elements
### Primary Colors
Configure your organization's primary color scheme:
Customize the following color elements:
* Primary brand color
* Secondary colors
* Accent colors
* Background colors
* Text colors
## Customization Options
### Logo Settings
* Upload organization logo
* Set logo dimensions
* Configure placement
* Define visibility rules
* Dark/light mode variants
### Color Scheme
* Primary colors
* Secondary palette
* System status colors
* Alert level indicators
* Background gradients
### Typography
* Font family selection
* Text sizes
* Font weights
* Line heights
* Letter spacing
### UI Elements
* Button styles
* Form elements
* Card designs
* Navigation items
* Modal windows
## Theme Configuration
### Light Mode
* Background colors
* Text colors
* UI element colors
* Contrast settings
* Accessibility options
### Dark Mode
* Dark theme colors
* Text visibility
* Element contrast
* Shadow effects
* Accent highlights
### System Elements
* Navigation bar
* Sidebar
* Headers
* Footers
* Action buttons
## Best Practices
### Brand Consistency
* Follow brand guidelines
* Maintain color harmony
* Ensure readability
* Consider accessibility
* Test across devices
### Visual Hierarchy
* Emphasize important elements
* Create clear contrast
* Use consistent spacing
* Implement proper scaling
* Maintain balance
### Accessibility
* Color contrast ratios
* Text readability
* Screen reader support
* Keyboard navigation
* Focus indicators
### Performance
* Optimize image sizes
* Minimize CSS
* Cache resources
* Load time considerations
* Responsive design
## Implementation Guide
### Basic Setup
1. Upload brand assets
2. Configure primary colors
3. Set typography
4. Adjust UI elements
5. Test appearance
### Advanced Configuration
1. Custom CSS rules
2. Component overrides
3. Theme variations
4. Responsive adjustments
5. Animation settings
### Testing
1. Cross-browser testing
2. Device compatibility
3. Accessibility validation
4. Performance checks
5. User feedback
# Case Statuses
Source: https://docs.casebender.com/en/settings/case-statuses/introduction
Configure and manage custom case statuses to track the lifecycle of cases in your security operations.
## Overview
The Case Statuses section enables you to create and manage custom status definitions for your cases. This feature helps you track the progression of cases through your incident response and investigation workflow, ensuring consistent case management across your organization.
## Managing Case Statuses
### Creating a New Status
Click the "Create" button to add a new case status:
Configure the basic status information:
* Status name
* Description
* Color indicator
* Icon selection
* Category/Phase
### Configuring Status Details
Provide comprehensive configuration for your case status:
Define detailed settings:
* Status behavior
* Workflow rules
* Required fields
* Team permissions
### Status Management
View and manage your configured case statuses:
The status list displays:
* Status name and icon
* Description
* Phase/Category
* Creation date
* Last modified
* Actions
## Default Status Types
### Initial Phase
* New
* Opened
* Assigned
* Triaged
### Investigation Phase
* Under Investigation
* Evidence Collection
* Analysis in Progress
* Pending Information
### Action Phase
* Containment
* Eradication
* Recovery
* Remediation
### Closure Phase
* Resolved
* Closed
* Archived
* Reopened
## Status Configuration
### Visual Elements
* Status colors
* Icon selection
* Phase indicators
* Priority badges
### Workflow Rules
* Status transitions
* Required actions
* Time limits
* Dependencies
### Field Requirements
* Mandatory fields
* Optional information
* Documentation needs
* Approval requirements
## Best Practices
### Status Design
* Clear naming conventions
* Logical progression
* Consistent terminology
* Intuitive organization
### Process Integration
* Align with procedures
* Define clear transitions
* Set completion criteria
* Enable tracking
### Team Collaboration
* Role assignments
* Handoff procedures
* Communication rules
* Responsibility matrix
### Quality Control
* Regular reviews
* Status audits
* Process validation
* Effectiveness metrics
## Using Case Statuses
### In Case Management
* Track investigation progress
* Monitor response actions
* Manage resources
* Ensure compliance
### In Workflow Automation
* Status-based triggers
* Automatic assignments
* Notification rules
* SLA tracking
### In Reporting
* Case metrics
* Resolution times
* Team performance
* Trend analysis
## Related Documentation
* [Case Management](../../cases/introduction.mdx)
# Custom Fields
Source: https://docs.casebender.com/en/settings/custom-fields/introduction
Create and manage custom fields to extend your case management capabilities in CaseBender.
## Overview
The Custom Fields section allows you to create and manage additional fields that can be used across your cases and tasks. This feature enables you to customize your data collection and organization according to your specific needs.
## Creating Custom Fields
### Step 1: Initialize Creation
Click the "Create" button to start creating a new custom field:
Fill out the basic information:
* Field name
* Description
* Category
* Required status
* Visibility settings
### Step 2: Select Field Type
Choose the appropriate field type for your data:
Available field types include:
* Text (Single line)
* Text Area (Multi-line)
* Number
* Date
* Select (Single choice)
* Multi-select
* Checkbox
* Radio buttons
* URL
* Email
* Phone number
### Step 3: Field Configuration Complete
After creation, the field will appear in the custom fields table:
The table displays:
* Field name
* Type
* Category
* Required status
* Creation date
* Last modified date
* Actions
## Field Types and Use Cases
### Text Fields
* Single line: Short text responses
* Text area: Detailed descriptions
* Rich text: Formatted content
### Numeric Fields
* Numbers: Quantities, measurements
* Currency: Financial values
* Percentage: Ratios, completion rates
### Selection Fields
* Dropdown: Single choice from options
* Multi-select: Multiple choices
* Radio buttons: Exclusive choices
* Checkboxes: Yes/No options
### Special Fields
* Date/Time: Temporal information
* URL: Web links
* Email: Contact information
* Phone: Contact numbers
## Best Practices
### Field Design
* Use clear, descriptive names
* Provide helpful descriptions
* Choose appropriate field types
* Set sensible default values
### Organization
* Group related fields
* Maintain consistent naming
* Use categories effectively
* Consider field order
### Validation
* Set appropriate constraints
* Define required fields
* Configure format validation
* Test field behavior
### Maintenance
* Review field usage
* Update obsolete fields
* Document changes
* Monitor performance impact
## Using Custom Fields
### In Cases
* Add to case forms
* Use in case views
* Include in reports
* Filter and sort
### In Tasks
* Task creation forms
* Task details
* Progress tracking
* Completion criteria
### In Reports
* Data analysis
* Custom metrics
* Export options
* Dashboard integration
## Related Documentation
* [Case Management](../../cases/introduction.mdx)
* [Task Management](../../tasks/introduction.mdx)
# AWS GuardDuty
Source: https://docs.casebender.com/en/settings/integrations/aws-guardduty
Ingest AWS GuardDuty findings into CaseBender by automatic polling (pull) or EventBridge webhook (push).
## Overview
The AWS GuardDuty integration (**INT-023**) ingests GuardDuty findings into CaseBender, enriches
them with MITRE ATT\&CK mapping and attack categorization, and turns them into alerts (and
optionally cases).
CaseBender pulls new findings directly from your AWS account on a schedule
using IAM credentials — no EventBridge rule required.
Alternatively, an EventBridge rule forwards findings to the CaseBender
ingestion endpoint.
**Recommended: enable Automatic polling.** It requires only a read-only IAM
key and no inbound endpoint. See
[Automatic polling](#inbound-automatic-polling-recommended).
Polling uses the official **AWS SDK** against the GuardDuty API
(`ListDetectors`, `ListFindings`, `GetFindings`).
## Capabilities
| Capability | Direction | Description |
| -------------------------- | --------- | ------------------------------------------------------------------------- |
| **Finding polling (pull)** | Inbound | CaseBender polls the GuardDuty API on a schedule and ingests new findings |
| Finding ingestion (push) | Inbound | EventBridge forwards findings to the ingestion endpoint |
| Observable extraction | Inbound | IPs, domains, access keys, S3 buckets, instance IPs |
| MITRE ATT\&CK correlation | Inbound | Finding types are mapped to tactics/techniques |
| Attack categorization | Inbound | Findings are categorized and given remediation guidance |
## Prerequisites
GuardDuty must be enabled in the AWS region(s) you want to monitor.
Create an IAM principal with a policy allowing `guardduty:ListDetectors`,
`guardduty:ListFindings`, and `guardduty:GetFindings`. Generate an access key ID + secret.
The CaseBender poller must reach the GuardDuty API endpoint for your region
(`guardduty..amazonaws.com`).
## Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **AWS GuardDuty** from the
**Cloud Security** category.
| Field | Description |
| --------------------------- | ----------------------------------------------------------- |
| AWS Access Key ID | IAM access key ID |
| AWS Secret Access Key | IAM secret access key |
| AWS Region | Region where GuardDuty is enabled (e.g. `us-east-1`) |
| Detector ID (optional) | Auto-discovered from the region if blank |
| Minimum severity (optional) | GuardDuty severity 1–8.9; only findings at/above are pulled |
| Option | Effect |
| ----------------------------- | ----------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of findings |
| `pollingIntervalMinutes` | How often to poll (default `5`) |
| `pollingInitialLookbackHours` | On first run, import findings updated within this window (default `24`) |
| `pollMaxItemsPerRun` | Safety cap on items ingested per run (default `500`) |
| Option | Effect |
| -------------------- | ---------------------------------------------------------- |
| `autoCreateCases` | Promote each finding to a **Case** (deduped by finding ID) |
| `minSeverityForCase` | Only auto-create cases at/above this severity |
## Inbound (automatic polling, recommended)
On each interval, CaseBender lists finding IDs updated since the last cursor (optionally
filtered by minimum severity), then fetches the full findings. On first run, findings updated
within `pollingInitialLookbackHours` are imported.
CaseBender advances the cursor to the newest `updatedAt`. Findings are **deduplicated by
finding ID**, so overlapping windows never create duplicates.
Each finding is normalized into a CaseBender alert with observables, MITRE tactics, attack
category, and remediation guidance.
Polling runs in CaseBender's background poller service. For multi-region coverage, create one
GuardDuty integration per region.
## Inbound (EventBridge webhook / push)
As an alternative, an EventBridge rule (with an API destination) can POST findings to:
```
POST https:///api/v1/ingest/guardduty
```
Requests are authenticated with the integration **API key** in the `x-api-key` header. Both the
raw finding and the EventBridge `{ "detail": { ... } }` envelope are accepted.
## Security considerations
* **Least privilege** — grant only the three read-only GuardDuty actions listed above.
* **Secret handling** — rotate the IAM access key on your organization's schedule; prefer keys
scoped to a dedicated integration user.
* **Network** — restrict egress to the GuardDuty regional endpoint.
## Troubleshooting
Confirm GuardDuty is enabled in the configured region, or set the Detector ID explicitly.
Verify the IAM key has `ListDetectors`, `ListFindings`, and `GetFindings`. Check the region
and that findings exist newer than the cursor. On first run only findings within
`pollingInitialLookbackHours` are imported.
**Make sure all CaseBender services are running** — with Docker, `docker compose ps` should
show the `worker` and `misp-processor` services `Up`.
The IAM policy is missing one of the required actions, or the key belongs to a different
account/region than expected.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [AWS GuardDuty documentation](https://docs.aws.amazon.com/guardduty/)
# Credentials and Connections
Source: https://docs.casebender.com/en/settings/integrations/credentials-and-connections
Store secrets in the governed vault and bind them to reusable integration connections.
## Overview
CaseBender separates secret material from connector configuration:
* A **credential** contains the encrypted authentication material and its version history.
* A **connection** selects a connector, non-secret endpoint configuration, organization scope, and live or test credential.
* A **binding** controls where a credential may be used.
Raw secrets are accepted only during create or rotate operations. They are not
returned to the browser, logs, exports, workflow definitions, or connector
manifests.
## Add a governed connection
Use **Settings → Integrations → Connections → Add integration**. The guided
flow creates the credential and connection as one operation:
1. Choose a certified connector and authentication method.
2. Enter non-secret endpoint or tenant values under **Connection details**.
3. Enter API keys, passwords, or application secrets under **Authentication**.
4. Review organization scope, requested OAuth scopes, and advanced host access.
5. Connect and run the initial health check.
Use separate credentials for test and production. Host restrictions are enforced
by the connector worker before outbound traffic is sent.
For authorization-code connectors such as Slack, choose the OAuth mode and
select **Authorize with vendor**. Casebender verifies signed state and PKCE,
exchanges the one-time code at the connector's allowlisted token endpoint, and
stores the resulting token as a new encrypted credential version. OAuth client
secrets and access tokens are never returned after the flow completes.
## Manage a connection
Select **Manage** on a Connections row to open the full settings workspace:
* **General** controls the name, description, organization scope, required
endpoint, enabled state, health summary, and connection test.
* **Authentication** shows the currently selected credential. Select
**Replace authentication** to use an existing compatible credential or create
a new one inline. Creating authentication here updates this connection; it
does not create another connection.
* **Automation** controls polling, webhook ingestion, automatic case creation,
synchronization, mappings, and provider actions.
* **Advanced** contains low-frequency transport and provider options, approved
hosts, connector information, webhook-key rotation, and the Danger zone.
Non-secret settings use one Save action and are synchronized to compatibility
records in the same transaction. If you close Manage with unsaved changes,
CaseBender asks before discarding them. Removing an integration from the
Advanced tab stops polling, ingestion, and workflow actions. Its encrypted
authentication remains in the Credential vault so an administrator can reuse
or revoke it separately.
A failed test does not delete the connection. Correct the endpoint or
authentication and retry from the same dialog.
## Rotate credentials and webhook keys
Open **Settings → Integrations → Credential vault** for the advanced encrypted
credential inventory. Create replacement authentication from the connection's
Authentication tab. Non-OAuth methods are encrypted and selected immediately.
OAuth returns to the same connection and selects the authorized credential
without creating a duplicate connection.
Credential rotation creates a new immutable version and makes it active without
rewriting workflow definitions. Webhook keys are shown only once when issued.
During a controlled rollover, the current and previous webhook key hashes can be
accepted; retire the previous key after producers have switched.
## Access control
Creating, rotating, exporting, or testing integration credentials requires the
integration administration permission and step-up authentication. Workflow
authors can select only connections visible to their current organization.
Never paste API keys into connector configuration, workflow inputs, or custom
HTTP headers. Store them as credentials so redaction, rotation, audit, and host
policy controls apply.
# CrowdStrike Falcon
Source: https://docs.casebender.com/en/settings/integrations/crowdstrike
Bi-directional integration between CaseBender and CrowdStrike Falcon for detection ingestion (pull or push) and disposition sync.
## Overview
The CrowdStrike Falcon integration (**INT-008**) ingests Falcon detections into CaseBender
and can push case dispositions back to Falcon when a case is closed.
Falcon detections are ingested — either **pulled automatically** on a
schedule (recommended) or **pushed** via a webhook — then normalized,
enriched with observables and MITRE ATT\&CK techniques, and turned into alerts.
When a linked CaseBender case is closed, the Falcon detection status is
updated with an audit comment.
**Recommended: enable Automatic polling.** CaseBender can pull new detections
on a schedule using the same Falcon API client — no webhook or SIEM connector
is required. See [Automatic polling](#inbound-automatic-polling-recommended).
This integration uses the **Falcon Alerts API v2** and authenticates with an
**OAuth2 API client** (client ID + secret) using the client-credentials flow.
## Capabilities
| Capability | Direction | Description |
| ---------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------- |
| **Detection polling (pull)** | Inbound | CaseBender polls the Alerts API on a schedule and ingests new detections automatically — no Falcon-side setup |
| Detection ingestion (push) | Inbound | Falcon detections are pushed via webhook and normalized into CaseBender alerts |
| Observable extraction | Inbound | IPs, file hashes, file names, hostnames, and users are extracted |
| MITRE ATT\&CK correlation | Inbound | Technique/tactic IDs are added as tags and TTPs |
| Disposition sync | Outbound | Detection status + comment are pushed on case close |
| Connection test | Bi-directional | Validates OAuth2 credentials and API access |
## Prerequisites
In the Falcon console, go to **Support and resources → API clients and keys**
and create an API client. Grant the **Alerts: Read** scope (and **Alerts:
Write** if you want outbound close-back). Copy the **Client ID** and **Secret**.
Note your Falcon cloud base URL (e.g. `https://api.crowdstrike.com`,
`https://api.us-2.crowdstrike.com`, or `https://api.eu-1.crowdstrike.com`).
The CaseBender poller service must be able to reach your Falcon API base URL.
## Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **CrowdStrike Falcon**
from the **EDR/XDR** category.
| Field | Description |
| ------------------------ | ------------------------------------------------------------- |
| API URL | Falcon cloud base URL (default `https://api.crowdstrike.com`) |
| Falcon API Client ID | The OAuth2 client ID |
| Falcon API Client Secret | The OAuth2 client secret |
In the **Automatic polling** card, turn on **Enable automatic polling** and set:
| Option | Effect |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of Falcon detections |
| `pollingIntervalMinutes` | How often to poll (default `5`, range 1–1440) |
| `pollingInitialLookbackHours` | On first run, import detections updated within this window (default `24`, range 1–168) |
| `pollMaxItemsPerRun` | Safety cap on items ingested per run (default `500`) |
| Option | Effect |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `autoCreateCases` | Promote each ingested detection to a **Case** (deduped by detection ID). When off, detections stay in the Alerts inbox |
| `minSeverityForCase` | Only auto-create cases at/above this severity |
## Inbound (automatic polling, recommended)
With **Automatic polling** enabled, the CaseBender poller periodically queries the Falcon
Alerts API and ingests new detections on its own.
On each interval, CaseBender queries the Alerts API v2 for composite IDs updated since the
last cursor, then fetches the full detection entities. On the first run there is no cursor,
so detections updated within `pollingInitialLookbackHours` are imported.
CaseBender advances a per-integration cursor to the newest `updated_timestamp` it has seen.
Detections are **deduplicated by detection ID**, so overlapping polling windows never create
duplicate alerts.
Each detection is normalized into a CaseBender alert — mapping severity, building the
title/description, extracting observables, and generating MITRE TTPs.
Polling runs in CaseBender's background poller service. Ensure that service can reach your
Falcon API base URL (directly or via your configured proxy).
## Inbound (webhook / push)
As an alternative to polling, Falcon (or an intermediary) can push detection payloads to the
CaseBender ingestion endpoint:
```
POST https:///api/v1/ingest/crowdstrike
```
Requests are authenticated with an integration **API key** in the `x-api-key` header. Falcon
webhook API keys are prefixed with `cbr_crowdstrike_`.
## Outbound: syncing case dispositions to Falcon
When a case is closed, the `case_closed` event is dispatched to the CrowdStrike handler. If the
case is linked to a Falcon detection (the detection ID is stamped onto the ingested alert), the
handler updates the detection status and adds an audit comment. Outbound close-back requires the
**Alerts: Write** scope on the API client.
## Security considerations
* **Least privilege** — grant **Alerts: Read** for inbound only; add **Alerts: Write** only if
you enable outbound close-back.
* **Secret handling** — the client secret is stored in the integration settings; rotate on your
organization's schedule.
* **Token caching** — access tokens are cached in memory and refreshed before expiry.
* **Network** — restrict egress to your Falcon API base URL.
## Troubleshooting
Verify the client ID, secret, and API base URL (region). Confirm the API client is enabled
and has the Alerts scope.
Confirm **Enable automatic polling** is on and the API client has the Alerts: Read scope.
Check the poller can reach your Falcon base URL. On first run only detections within
`pollingInitialLookbackHours` are imported.
**Make sure all CaseBender services are running.** Detections are fetched by the background
processor and turned into alerts (and optionally cases) by the background **worker**. With
Docker, run `docker compose ps` and confirm the `worker` and `misp-processor` services are
`Up`.
Ensure the API client has the Alerts: Write scope and the case is linked to a Falcon
detection. Check the case timeline for the sync result.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [CrowdStrike Falcon API documentation](https://falcon.crowdstrike.com/documentation/)
# Google Cloud SCC
Source: https://docs.casebender.com/en/settings/integrations/gcp-scc
Ingest Google Cloud Security Command Center findings into CaseBender by automatic polling (pull) or notification webhook (push).
## Overview
The Google Cloud Security Command Center (SCC) integration (**INT-009**) ingests SCC findings
into CaseBender and turns them into alerts (and optionally cases).
CaseBender pulls new findings directly from SCC on a schedule using a service
account — no Pub/Sub notification required.
Alternatively, an SCC notification (via Pub/Sub + Cloud Function) forwards
findings to the CaseBender ingestion endpoint.
**Recommended: enable Automatic polling.** It requires only a read-only service
account and no inbound endpoint. See
[Automatic polling](#inbound-automatic-polling-recommended).
Polling uses the official **Google Cloud SDK** (`@google-cloud/security-center`) to list
findings via the SCC v1 API.
## Capabilities
| Capability | Direction | Description |
| -------------------------- | --------- | -------------------------------------------------------------------------- |
| **Finding polling (pull)** | Inbound | CaseBender polls the SCC API on a schedule and ingests new ACTIVE findings |
| Finding ingestion (push) | Inbound | Pub/Sub notification forwards findings to the ingestion endpoint |
| Observable extraction | Inbound | IPs and domains from finding indicators |
| Category tagging | Inbound | Finding category, class, and resource type become tags |
## Prerequisites
In Google Cloud IAM, create a service account and download a **JSON key**. Grant it the
**Security Center Findings Viewer** role (`roles/securitycenter.findingsViewer`) at the
organization or project level.
Record your numeric **organization ID** (recommended) or a **project ID**.
The CaseBender poller must reach `securitycenter.googleapis.com` and
`oauth2.googleapis.com`.
## Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **Google Cloud SCC** from the
**Cloud Security** category.
| Field | Description |
| -------------------------- | ----------------------------------------------------- |
| Organization ID | Numeric GCP organization ID |
| Project ID (optional) | Falls back to project-level findings if no org is set |
| Service Account Key (JSON) | Paste the full JSON key |
| Option | Effect |
| ----------------------------- | ----------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of findings |
| `pollingIntervalMinutes` | How often to poll (default `5`) |
| `pollingInitialLookbackHours` | On first run, import findings updated within this window (default `24`) |
| `pollMaxItemsPerRun` | Safety cap on items ingested per run (default `500`) |
| Option | Effect |
| -------------------- | ------------------------------------------------------------ |
| `autoCreateCases` | Promote each finding to a **Case** (deduped by finding name) |
| `minSeverityForCase` | Only auto-create cases at/above this severity |
## Inbound (automatic polling, recommended)
On each interval, CaseBender lists ACTIVE findings with `eventTime` at/after the last cursor,
ordered by event time. On first run, findings within `pollingInitialLookbackHours` are
imported.
CaseBender advances the cursor to the newest `eventTime`. Findings are **deduplicated by
finding name**, so overlapping windows never create duplicates.
Each finding is normalized into a CaseBender alert with observables and category tags.
Polling runs in CaseBender's background poller service. Ensure it can reach
`securitycenter.googleapis.com` (directly or via your proxy).
## Inbound (notification webhook / push)
As an alternative, an SCC notification config (Pub/Sub → Cloud Function) can POST findings to:
```
POST https:///api/v1/ingest/gcpscc
```
Requests are authenticated with the integration **API key** in the `x-api-key` header. The
`{ "finding": { ... }, "resource": { ... } }` payload shape is expected.
## Security considerations
* **Least privilege** — grant only **Security Center Findings Viewer**.
* **Secret handling** — the service account JSON key is stored in the integration settings;
rotate it on your organization's schedule and prefer a dedicated integration service account.
* **Network** — restrict egress to `securitycenter.googleapis.com` and `oauth2.googleapis.com`.
## Troubleshooting
Paste the entire JSON key file contents, including the surrounding braces.
Confirm the service account has the Findings Viewer role at the org/project you configured,
and that ACTIVE findings exist newer than the cursor. On first run only findings within
`pollingInitialLookbackHours` are imported.
**Make sure all CaseBender services are running** — with Docker, `docker compose ps` should
show the `worker` and `misp-processor` services `Up`.
The service account lacks `securitycenter.findings.list` at the requested scope, or the
organization/project ID is incorrect.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [Security Command Center documentation](https://cloud.google.com/security-command-center/docs)
# Integrations
Source: https://docs.casebender.com/en/settings/integrations/introduction
Configure and manage integrations with external services and systems in your CaseBender instance.
## One integration workspace
Open **Settings → Integrations** to configure vendors, monitor their health,
and manage authentication. Administrators see three tabs:
* **Connections** is the default view. A connection combines one connector,
its non-secret endpoint settings, and governed authentication.
* **Health** shows connection diagnostics and connector execution activity.
* **Credential vault** is an advanced inventory for encrypted credentials,
revocation, and rotation.
The Connections tab presents every configured integration in one list,
regardless of its internal execution implementation. Analysts retain read-only
access. Only organization and super administrators can add, test, or manage
connections.
## Certified connectors
* [Splunk](/en/settings/integrations/splunk)
* [CrowdStrike Falcon](/en/settings/integrations/crowdstrike)
* [Microsoft Defender XDR](/en/settings/integrations/microsoft-defender)
* [Microsoft Sentinel](/en/settings/integrations/microsoft-sentinel)
* [AWS GuardDuty](/en/settings/integrations/aws-guardduty)
* [ServiceNow](/en/settings/integrations/servicenow)
* [Jira](/en/settings/integrations/jira)
* [Slack](/en/settings/integrations/slack)
* [Palo Alto Networks](/en/settings/integrations/paloalto)
* [MISP](/en/settings/integrations/misp)
## Add an integration
1. Select **Add integration** from the Connections tab.
2. Choose a provider from the searchable logo catalog.
3. Enter a friendly connection name and choose an authentication method.
4. Complete the connector-defined Connection details and Authentication
fields. Slugs, connector versions, and fixed endpoints are derived
automatically.
5. Review organization scope and requested OAuth scopes. Custom approved hosts
and platform-wide visibility are under **Advanced settings**.
6. For connectors with guided setup, select **Connect integration**.
Casebender saves the credential and connection as one operation, then
performs a health check. Other providers continue into their established
provider-specific configuration.
If a vendor health check fails, the connection remains saved. Select
**Manage** from its row to correct the endpoint or authentication and retry.
Webhook keys are displayed once after setup and must be copied immediately.
OAuth connectors redirect to the vendor and return to the setup wizard. Only a
non-secret draft is stored in the browser while authorization is in progress.
## Manage integration settings
Select **Manage** on an integration to open one settings workspace:
* **General** owns identity, organization scope, endpoint, enabled state, and
health testing.
* **Authentication** owns encrypted secrets and OAuth authorization. Replacing
authentication creates and selects a credential for the existing connection;
it never starts the Add integration wizard or creates a second connection.
* **Automation** owns polling, webhook ingestion, synchronization, mappings,
and automatic provider behavior.
* **Advanced** owns transport and low-frequency provider controls, approved
hosts, webhook-key rotation, and removal.
CaseBender stores these controls once and mirrors only the required
compatibility values for older ingestion consumers. Secret fields never appear
in Automation or Advanced.
## Best Practices
### Setting up integrations
* Choose names that identify the environment and tenant.
* Use guided connector setup when it is available for new workflow automations.
* Keep custom private-host access as narrow as possible.
* Use **Manage** to disable unused connections without deleting audit history.
### Security Considerations
* Never paste secrets into endpoint settings or workflow inputs.
* Use organization-scoped connections unless platform-wide access is required.
* Rotate or revoke credentials from the advanced vault.
* Monitor failures from the Health tab.
### Maintenance
* Regularly verify integration status
* Update configurations as needed
* Monitor performance metrics
* Keep documentation current
# Jira
Source: https://docs.casebender.com/en/settings/integrations/jira
Configure governed Jira issue automation and authenticated synchronization.
## Overview
The Jira connector supports Jira Software and Jira Service Management project
discovery, issue creation, updates, comments, transitions, issue linking, and
authenticated inbound synchronization. Connection authentication is stored in
the credential vault and is never returned from management APIs.
## Configure
Create an Atlassian API token for a dedicated service account with access
only to the required projects.
In **Settings → Integrations**, select **Add integration**, choose **Jira**, and enter the Jira host,
service-account email, and API token.
Bind the credential to the Jira host and verify the connection before using
it in a workflow.
In the connection's **Automation** and **Advanced** tabs, configure the
synchronization direction, conflict behavior, default project and issue
type, and any explicit mappings. Saving a changed policy increments its
version. Durable outbound events retain the policy version and snapshot that
created them.
## Governance and mappings
The four automation controls are independent:
* **Create issues automatically** handles case creation and alert promotion.
* **Synchronize task creation** creates and links one Jira issue for a new task.
* **Synchronize case updates** sends linked case changes to Jira.
* **Synchronize case closure** sends closure details and uses a configured
transition when one matches.
Choose **Outbound only**, **Inbound only**, or **Bidirectional**. Inbound-only
policy cannot be saved while outbound automation is enabled. Conflict policy is
evaluated against the remote update time and the most recent local/outbound
change:
* **Newest update wins** applies only the newer change.
* **CaseBender wins** retains local state when Jira is not newer.
* **Jira wins** applies authenticated Jira changes.
* **Manual resolution** suppresses conflicting inbound changes for operator
review.
Mappings are JSON objects. Keys are matched case-insensitively. Project and
issue-type mappings can use a CaseBender case type, source, or event type such
as `TaskCreated`; the default project and issue type are used when no mapping
matches. Status mappings use Jira transition IDs for outbound changes. Priority
mappings use CaseBender severities `1` through `4`. Assignee mappings map a
CaseBender user ID or email to a Jira account ID. Custom-field mappings map a
CaseBender custom-field name to a Jira `customfield_...` identifier.
The **Unmapped values** policy either leaves the target field unchanged
(`ignore`) or fails the operation for operator review (`error`).
## Configure the inbound webhook
Use the ingestion service URL ending in `/v1/sources/jira` (or the equivalent
path exposed by your reverse proxy). Every Jira webhook request must include:
```text theme={null}
x-casebender-connection-id:
x-casebender-webhook-secret:
```
`Authorization: Bearer ` may replace
`x-casebender-webhook-secret`. If supplied,
`x-casebender-organization-id` must match the connection's owning organization.
Configure issue create, update, delete, transition, assignment, priority, and
comment events according to the inbound fields you enabled.
CaseBender stores a hash of the webhook secret, not the raw value. Rotation
accepts the current and immediately previous hash so operators can update Jira
without an outage. Rotate again only after Jira is using the new secret.
Webhook receipts store identifiers, hashes, state, and sanitized errors; raw
webhook payloads and secrets are not retained. Duplicate delivery identifiers
or payload hashes are acknowledged without applying the change twice.
## Outbound automation reliability
Outbound operations use a tenant-scoped durable outbox. Attempts, policy
snapshot, correlation ID, remote status code, and a path-only request summary
are retained. Response bodies, authorization headers, credentials, and webhook
payloads are not written to operations or audit records.
Retries use exponential backoff. Events that exhaust their attempt budget move
to **DEAD\_LETTER**. From **Settings → Integrations → Health**, an integration
administrator can retry a failed event immediately or replay a dead-letter
event with additional attempts. Recovery reuses the original immutable payload
and idempotency key.
Inbound processing uses an ownership lease. A queue retry may reclaim
`PROCESSING` only after the lease expires. The Health view can release an
expired lease, but it does not recreate the Jira payload; the existing queue
retry or Jira redelivery must still provide it.
## Troubleshooting
1. Test the connection and verify the dedicated service account can browse the
selected project and perform each enabled action.
2. Confirm the connection is enabled, organization-scoped, and has a live
credential.
3. Verify the Jira webhook sends the connection ID and current secret to the
ingestion endpoint.
4. Review the policy version, sync direction, conflict policy, unmapped policy,
and recent failures in the Health view.
5. Correct invalid project keys, issue types, transition IDs, priorities,
account IDs, or custom-field IDs before retrying outbound work.
6. For a failed inbound receipt, rely on the worker queue retry or redeliver the
event from Jira. CaseBender cannot reconstruct a webhook because raw payloads
are intentionally not stored.
## Rollback
To stop new side effects, disable the connection or turn off the affected
automation controls. To roll back a policy, restore the previous non-secret
mapping values and save; this publishes a new version rather than rewriting
historical outbox snapshots. Existing dead-letter events keep their original
policy and should be replayed only after confirming that policy is still safe.
# Microsoft Defender XDR
Source: https://docs.casebender.com/en/settings/integrations/microsoft-defender
Bi-directional integration between CaseBender and Microsoft Defender XDR (Windows Defender) for alert/incident ingestion and disposition sync.
## Overview
The Microsoft Defender XDR integration (**INT-021**) provides **bi-directional** synchronization
between CaseBender and Microsoft's extended detection and response platform, including
**Microsoft Defender for Endpoint (MDE)** and **Microsoft Defender XDR**.
Defender incidents, including their child alerts, are **pulled
automatically** on a schedule (recommended). Standalone Defender alerts can
be **pushed** via a webhook. Both paths normalize and enrich records with
observables and MITRE ATT\&CK techniques.
When a CaseBender case is closed, the linked Defender alert/incident is updated with the
matching status, classification, and an audit comment via Microsoft Graph.
**Recommended: enable Automatic polling.** CaseBender can pull new Defender
incidents on a schedule using the same Azure AD credentials — no Logic App,
Sentinel automation rule, or webhook forwarder is required on the Microsoft
side. See [Automatic polling](#inbound-automatic-polling-recommended) below.
This integration uses the **Microsoft Graph Security API** (`https://graph.microsoft.com/v1.0/security`).
It authenticates with an **Azure AD (Entra ID) application** using the OAuth2 client-credentials flow.
## Capabilities
| Capability | Direction | Description |
| --------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **Incident polling (pull)** | Inbound | CaseBender polls the Graph Security API on a schedule and ingests new incidents automatically — no Microsoft-side setup |
| Alert ingestion (push) | Inbound | Defender alerts are pushed via webhook and normalized into CaseBender alerts |
| Incident ingestion | Inbound | Defender incidents (with child alerts) are ingested |
| Observable extraction | Inbound | IPs, URLs, file hashes, file names, hostnames, and user accounts are extracted from evidence |
| Asset extraction | Inbound | Device hostname, IP, and OS platform are captured from `devices[]` |
| MITRE ATT\&CK correlation | Inbound | Technique IDs are added as tags and TTPs (e.g. `mitre:T1078`) |
| Alert disposition sync | Outbound | Alert `status`, `classification`, `determination`, and comments are pushed on case close |
| Incident disposition sync | Outbound | Incident `status`, `classification`, `determination`, and comments are pushed on case close |
| Connection test | Bi-directional | Validates OAuth2 credentials and Graph Security API access |
## Prerequisites
A Microsoft Entra ID (Azure AD) tenant with Microsoft Defender XDR or Microsoft Defender
for Endpoint licensed and enabled. You need permission to register applications and grant
admin consent.
The CaseBender deployment must be able to reach:
* `https://login.microsoftonline.com` (OAuth2 token endpoint)
* `https://graph.microsoft.com` (Graph Security API)
You must be able to create and manage integrations in **Settings → Integrations**.
## Part A — Register an Azure AD application
In the [Microsoft Entra admin center](https://entra.microsoft.com), go to
**Identity → Applications → App registrations → New registration**. Give it a name
(e.g. `CaseBender Defender Integration`) and register it.
From the application **Overview**, copy the **Application (client) ID** and the
**Directory (tenant) ID**. You will enter these into CaseBender.
Under **Certificates & secrets → New client secret**, create a secret and copy its
**Value** immediately (it is only shown once).
Under **API permissions → Add a permission → Microsoft Graph → Application permissions**,
add the scopes for the direction(s) you need and then click **Grant admin consent**:
| Permission | Required for | Purpose |
| -------------------------------- | ----------------------------- | ---------------------------------------------------- |
| `SecurityAlert.Read.All` | Inbound (polling / ingestion) | Read Defender alerts |
| `SecurityIncident.Read.All` | Inbound (polling / ingestion) | Read Defender incidents |
| `SecurityAlert.ReadWrite.All` | Outbound (close-back) | Read **and update** Defender alerts on case close |
| `SecurityIncident.ReadWrite.All` | Outbound (close-back) | Read **and update** Defender incidents on case close |
**Read-only is enough for polling.** If you only pull incidents/alerts into CaseBender,
grant the two `Read.All` scopes. The `ReadWrite.All` scopes are required **only** for the
optional outbound close-back (`syncCaseClose`) — closing a Defender alert/incident from
CaseBender. Since `ReadWrite.All` also includes read access, granting just the two
`ReadWrite.All` scopes covers both directions.
Use **Application** permissions (not Delegated). The integration runs headless with the
client-credentials flow and requires tenant admin consent.
## Part B — Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **Microsoft Defender XDR** from the
**EDR/XDR** category.
Provide the values captured in Part A:
| Field | Description |
| -------------- | ----------------------- |
| `tenantId` | Directory (tenant) ID |
| `clientId` | Application (client) ID |
| `clientSecret` | Client secret value |
In the **Automatic polling** card, turn on **Enable automatic polling** and set:
| Option | Effect |
| ----------------------------- | ------------------------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of Defender incidents |
| `pollingIntervalMinutes` | How often to poll (default `5`, range 1–1440) |
| `pollingInitialLookbackHours` | On first run, import incidents updated within this window (default `24`, range 1–168) |
See [Automatic polling](#inbound-automatic-polling-recommended) for how it works.
Enable the behaviors you need:
| Option | Effect |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `syncCaseClose` | **Master switch** for outbound. When on (default), closing a linked case pushes the classification + an audit comment to Defender |
| `closeAlertsOnCaseClose` | Additionally set the linked Defender **alert** status to `resolved` |
| `closeIncidentsOnCaseClose` | Additionally set the linked Defender **incident** status to `resolved` |
| `autoCreateCases` | Automatically promote each ingested Defender record to a **Case** (deduped by incident ID). When off, records stay in the Alerts inbox for manual promotion |
With `syncCaseClose` on but both `close…OnCaseClose` toggles off, CaseBender still
writes the classification and audit comment to Defender — it just won't flip the
Defender entity to `resolved`.
Use **Test Connection** to validate. CaseBender requests an OAuth2 token and calls
`GET /security/alerts_v2?$top=1`.
A `403` response during the test is treated as **success** — it confirms authentication
worked even when the app has not yet been granted read scope on that specific endpoint.
## Inbound (automatic polling, recommended)
With **Automatic polling** enabled, CaseBender periodically calls the Graph Security API and
ingests new incidents on its own. This is the simplest and most reliable path: it needs **no
Logic App, Sentinel automation rule, or webhook forwarder** — only the Azure AD app
registration you already created in Part A.
### How it works
On each interval (`pollingIntervalMinutes`), CaseBender requests incidents updated since
the last cursor:
```
GET https://graph.microsoft.com/v1.0/security/incidents
?$filter=lastUpdateDateTime gt
&$expand=alerts
&$orderby=lastUpdateDateTime asc
```
On the very first run there is no cursor, so incidents updated within
`pollingInitialLookbackHours` are imported.
CaseBender advances a per-integration cursor to the newest `lastUpdateDateTime` it has
seen, so each run only fetches new activity. Incidents are also **deduplicated by
Defender incident ID**, so an incident is never ingested twice — even if the polling
window overlaps.
Each incident (and its expanded child alerts) is normalized into a CaseBender alert —
mapping severity, building the title/description, extracting observables and device
assets, and generating MITRE TTPs. The Defender incident ID is stamped onto the alert so
outbound close-sync can find it later.
Polling requires the app's `SecurityIncident.Read.All` (covered by
`SecurityIncident.ReadWrite.All`). With **`autoCreateCases` enabled**, each polled incident
becomes a **Case** automatically (deduplicated by incident ID) — this matches the "pull
incident → work it as a case" flow. With it disabled, incidents land in the **Alerts** inbox
for manual promotion. Either way the Defender link is preserved so closing the case syncs
back to Defender.
Polling runs in CaseBender's background poller service. Ensure that service can reach
`login.microsoftonline.com` and `graph.microsoft.com` (directly or via your configured
proxy). On proxy-only networks, see the proxy section of the deployment guide.
## Inbound (webhook / push)
As an alternative (or in addition) to polling, Defender — or an intermediary such as Logic
Apps, Sentinel, or a webhook forwarder — can push alert/incident payloads to the CaseBender
ingestion endpoint.
### Endpoint
The sender posts alert/incident payloads to the CaseBender ingestion endpoint:
```
POST https:///api/v1/ingest/defender
```
Requests are authenticated with an integration **API key** passed in the `x-api-key` header
(the `authorization: Bearer ` header is also accepted). Defender webhook API keys are
prefixed with `cbr_defender_`.
### Payload formats
Both a **batch** format (Graph `value[]` array) and a **single alert** object are supported.
```bash Batch (Graph value[]) theme={null}
curl -X POST "https:///api/v1/ingest/defender" \
-H "x-api-key: cbr_defender_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"value": [
{
"id": "da637...",
"incidentId": "12345",
"title": "Suspicious PowerShell execution",
"severity": "high",
"status": "new",
"classification": "unknown",
"createdDateTime": "2026-07-03T18:20:00Z",
"mitreTechniques": ["T1059.001"],
"evidence": [
{ "@odata.type": "#microsoft.graph.security.fileEvidence",
"sha256": "9f2b...", "fileName": "payload.ps1" }
]
}
]
}'
```
```bash Single alert theme={null}
curl -X POST "https:///api/v1/ingest/defender" \
-H "x-api-key: cbr_defender_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"id": "da637...",
"title": "Malware detected on endpoint",
"severity": "medium",
"status": "new",
"createdDateTime": "2026-07-03T18:20:00Z"
}'
```
A successful request returns HTTP `202 Accepted`:
```json theme={null}
{ "success": true, "processed": 1, "failed": 0 }
```
### Processing pipeline
The payload flows through CaseBender's ingestion services:
Production gateways (installer nginx, Kubernetes HTTPRoute, OpenShift) send
`POST /api/v1/ingest/defender` to the ingestion service. The Next.js
`/api/v1/ingest/[source]` route is local/dev only.
The ingestion service authenticates the API key, validates the payload, and publishes each
alert to the processing queue.
The Defender processor normalizes each record into a CaseBender alert — mapping severity,
building the title/description, extracting observables and device assets, and generating
MITRE TTPs.
### Data mapping reference
**Severity mapping** (Defender → CaseBender 1–4):
| Defender severity | CaseBender severity |
| ----------------- | ------------------- |
| `high` | 1 |
| `medium` | 2 |
| `low` | 3 |
| `informational` | 4 |
| `unknown` | 3 |
**Alert type mapping** (Defender category → governed CaseBender Alert type):
CaseBender accepts both the current Graph `categories[]` collection and the deprecated
single `category` field. Portal labels and Graph values are normalized, so values such as
`Command and control` and `CommandAndControl` are equivalent.
| CaseBender Alert type | Defender categories |
| --------------------- | ---------------------------------------------------------------------- |
| `malware` | Malware, Ransomware, Unwanted software |
| `identity` | Privilege escalation, Credential access, Permissions |
| `data-protection` | Exfiltration, Collection, Data loss prevention, Information governance |
| `endpoint` | Persistence, Execution, Defense evasion, Discovery |
| `network` | Command and control, Lateral movement, Initial access |
| `vulnerability` | Exploit |
| `availability` | Impact |
| `phishing` | Mail flow |
| `other` | Suspicious activity, Threat management, Others |
When an incident's child alerts contain multiple categories, CaseBender applies a stable
priority so a specific response domain wins over `other`. Missing and unknown future Defender
categories remain `unclassified` and do not block ingestion.
**Observable extraction** (from `evidence[]`):
| Evidence field | Observable type |
| --------------- | ------------------------- |
| `ipAddress` | `ip` |
| `url` | `url` |
| `sha256` | `hash` |
| `fileName` | `filename` |
| `deviceDnsName` | `hostname` |
| `userAccount` | `user` (`DOMAIN\account`) |
**Tags** applied on ingest include `defender`, `xdr`, one `category:` per Defender
category, `incident` (for incidents), and one `mitre:` tag per MITRE technique.
Ingested records default to **TLP:2** and **PAP:2**.
## Outbound: Syncing case dispositions to Defender
When a case is closed in CaseBender, the `case_closed` event is dispatched to the Defender
handler. If the case is linked to a Defender alert or incident, CaseBender pushes the
resolution back through the Graph Security API.
### How the linked Defender entity is resolved
The handler looks for the Defender identifiers in this order:
1. `extraData.defenderAlertId` / `extraData.defenderIncidentId` on the case
2. `sourceRef` when `extraData.source === "defender"`
3. The **Defender alert(s) linked to the case** — the ingest pipeline stamps the Defender
incident/alert ID onto each alert's `customFields`, so a case promoted from a polled or
webhook Defender alert resolves automatically, regardless of how it was created.
If no alert or incident ID is found, the case close is skipped for this integration.
### Resolution → classification mapping
| CaseBender resolution | Defender classification |
| --------------------- | ------------------------------- |
| `TruePositive` | `truePositive` |
| `FalsePositive` | `falsePositive` |
| `Duplicate` | `informationalExpectedActivity` |
| `NoImpact` | `informationalExpectedActivity` |
| *(other / none)* | `truePositive` (default) |
On close, CaseBender applies the mapped `classification` and adds a comment such as:
```
Case closed in CaseBender with resolution:
```
It additionally sets the Defender entity `status` to `resolved` when the matching toggle
(`closeAlertsOnCaseClose` for alerts, `closeIncidentsOnCaseClose` for incidents) is enabled.
The outcome is written to the case timeline so analysts can confirm the sync.
`syncCaseClose` is the **master switch** for outbound sync (default on). When it is off, no
outbound calls are made. Alert updates use the modern `/security/alerts_v2/{id}` endpoint;
incident updates use `/security/incidents/{id}`.
## Security considerations
* **Secret handling** — the client secret is stored in the integration settings; rotate it
on the schedule your organization requires and update the integration when you do.
* **Least privilege** — for inbound-only deployments grant just `SecurityAlert.Read.All` and
`SecurityIncident.Read.All`; add the matching `ReadWrite.All` scopes only if you enable
outbound close-back. Do not add broader Graph scopes.
* **Token caching** — access tokens are cached in memory per integration and refreshed one
minute before expiry; no tokens are persisted to disk.
* **Webhook keys** — treat the `cbr_defender_` API key as a secret. Rotate it if exposed and update
the sender configuration.
* **Network** — restrict egress to `login.microsoftonline.com` and `graph.microsoft.com`.
## Troubleshooting
Verify the `tenantId`, `clientId`, and `clientSecret`. Confirm the client secret has not
expired and that admin consent was granted for the Graph application permissions.
The `x-api-key` header is missing or invalid. Confirm you are sending the `cbr_defender_` key that
matches the integration's configured webhook API key.
The payload had neither a `value[]` array nor a top-level `id`. Send a Graph batch object
or a single alert object.
Confirm **Enable automatic polling** is on and the connection test passes. Check that the
app has `SecurityIncident.Read.All` (or `ReadWrite.All`) with admin consent, that the
poller service can reach `graph.microsoft.com` (and your proxy, if any), and that there
are incidents newer than the cursor. On first run only incidents within
`pollingInitialLookbackHours` are imported. Polled incidents land in the **Alerts** inbox.
**Make sure all CaseBender services are running.** Incidents are fetched by the background
processor and turned into alerts (and optionally cases) by the background **worker**. If the
worker isn't running, incidents are fetched but never show up. With Docker, run
`docker compose ps` and confirm the `worker` and `misp-processor` services are `Up`; if not,
run `docker compose up -d`. The standard installer and quickstart set everything up
automatically — you do not need to configure any queue or Redis settings yourself.
Ensure `syncCaseClose` is on (it is the master switch). To also mark the Defender entity
`resolved`, enable `closeAlertsOnCaseClose` / `closeIncidentsOnCaseClose`. The case must be
linked to a Defender alert/incident — closing a case promoted from a polled/webhook
Defender alert resolves the link automatically. Check the case timeline for the sync
result.
A `403` means the Azure AD app lacks write permission — confirm `SecurityAlert.ReadWrite.All`
and `SecurityIncident.ReadWrite.All` are granted with admin consent. A `404` on an alert
update usually means a legacy endpoint; CaseBender uses `/security/alerts_v2/{id}` for
modern Defender XDR alerts.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [Microsoft Graph Security API](https://learn.microsoft.com/en-us/graph/api/resources/security-api-overview)
* [Microsoft Defender XDR](https://learn.microsoft.com/en-us/defender-xdr/)
# Microsoft Sentinel
Source: https://docs.casebender.com/en/settings/integrations/microsoft-sentinel
Bi-directional integration between CaseBender and Microsoft Sentinel for incident ingestion (pull or push) and disposition sync.
## Overview
The Microsoft Sentinel integration (**INT-009**) ingests Sentinel incidents into CaseBender and
can push case dispositions back to Sentinel when a case is closed.
Sentinel incidents are ingested — either **pulled automatically** on a
schedule (recommended) or **pushed** via a webhook / Logic App — then
normalized and turned into alerts.
When a linked CaseBender case is closed, the Sentinel incident status and
classification are updated with an audit comment.
**Recommended: enable Automatic polling.** CaseBender can pull new incidents on
a schedule directly from your Log Analytics workspace — no Logic App, data
connector, or inbound endpoint is required. See
[Automatic polling](#inbound-automatic-polling-recommended).
This integration uses the **Azure Security Insights REST API** and
authenticates with an **Azure AD (Entra ID) application** using the OAuth2
client-credentials flow (scope `management.azure.com`).
## Capabilities
| Capability | Direction | Description |
| ------------------------------ | -------------- | ------------------------------------------------------------------------------------------------ |
| **Incident polling (pull)** | Inbound | CaseBender polls the Security Insights API on a schedule and ingests new incidents automatically |
| Incident ingestion (push) | Inbound | Sentinel incidents are pushed via webhook / Logic App |
| Observable & entity extraction | Inbound | Entities are extracted from the incident |
| Disposition sync | Outbound | Incident `status` + `classification` + comment are pushed on case close |
| Connection test | Bi-directional | Validates OAuth2 credentials and workspace access |
## Prerequisites
In the [Microsoft Entra admin center](https://entra.microsoft.com), register an app and
create a **client secret**. Record the **Directory (tenant) ID**, **Application (client)
ID**, and secret value.
Grant the app the **Microsoft Sentinel Reader** role on the Sentinel-enabled Log Analytics
workspace (for inbound). For outbound close-back, grant **Microsoft Sentinel Responder**.
Record the **Subscription ID**, **Resource Group**, and **Log Analytics workspace name**.
The CaseBender poller must reach `login.microsoftonline.com` and `management.azure.com`.
## Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **Microsoft Sentinel** from the
**SIEM** category.
| Field | Description |
| ---------------------------- | ------------------------------------------- |
| Azure Tenant ID | Directory (tenant) ID |
| Application (Client) ID | The app registration client ID |
| Client Secret | The client secret value |
| Subscription ID | Azure subscription containing the workspace |
| Resource Group | Resource group of the workspace |
| Log Analytics Workspace Name | Sentinel-enabled workspace to poll |
| Option | Effect |
| ----------------------------- | ------------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of Sentinel incidents |
| `pollingIntervalMinutes` | How often to poll (default `5`, range 1–1440) |
| `pollingInitialLookbackHours` | On first run, import incidents modified within this window (default `24`) |
| `pollMaxItemsPerRun` | Safety cap on items ingested per run (default `500`) |
| Option | Effect |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `autoCreateCases` | Promote each ingested incident to a **Case** (deduped by incident name). When off, incidents stay in the Alerts inbox |
| `minSeverityForCase` | Only auto-create cases at/above this severity |
## Inbound (automatic polling, recommended)
On each interval, CaseBender lists incidents from the workspace with
`properties/lastModifiedTimeUtc` greater than the last cursor, ordered ascending. On the
first run, incidents modified within `pollingInitialLookbackHours` are imported.
CaseBender advances a per-integration cursor to the newest `lastModifiedTimeUtc`. Incidents
are **deduplicated by incident name**, so overlapping polling windows never create
duplicates.
Each incident is normalized into a CaseBender alert, and the Sentinel incident identifier is
preserved so outbound close-sync can find it later.
Polling runs in CaseBender's background poller service. Ensure it can reach
`login.microsoftonline.com` and `management.azure.com` (directly or via your proxy).
## Outbound: syncing case dispositions to Sentinel
When a linked case is closed, CaseBender updates the Sentinel incident `status` (to `Closed`)
and `classification`, and adds an audit comment. Outbound requires the **Microsoft Sentinel
Responder** role.
## Security considerations
* **Least privilege** — grant **Sentinel Reader** for inbound only; add **Sentinel Responder**
only if you enable outbound close-back.
* **Secret handling** — rotate the client secret on your organization's schedule.
* **Network** — restrict egress to `login.microsoftonline.com` and `management.azure.com`.
## Troubleshooting
Verify the tenant/client IDs and secret, and that the app has the Sentinel Reader role on
the workspace. Confirm the subscription ID, resource group, and workspace name are correct.
Confirm **Enable automatic polling** is on and the workspace coordinates are correct. Check
the poller can reach `management.azure.com`. On first run only incidents within
`pollingInitialLookbackHours` are imported.
**Make sure all CaseBender services are running** — with Docker, `docker compose ps` should
show the `worker` and `misp-processor` services `Up`.
Ensure the app has the Sentinel Responder role and the case is linked to a Sentinel
incident. Check the case timeline for the sync result.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [Microsoft Sentinel REST API](https://learn.microsoft.com/en-us/rest/api/securityinsights/)
# MISP
Source: https://docs.casebender.com/en/settings/integrations/misp
Search, publish, and enrich threat intelligence with MISP.
## Overview
The MISP connector searches attributes, retrieves events, creates events, adds
attributes, and records sightings from CaseBender.
## Configure
Create a dedicated MISP automation user with permissions limited to the
organizations, sharing groups, and distribution levels you require.
In **Settings → Integrations**, select **Add integration**, choose **MISP**, enter the instance URL and
API key, and add the MISP hostname to the allowed-host list.
Bind the credential to the MISP URL and verify the server version can be
retrieved.
## Available actions
* Search attributes and retrieve events
* Create events and attributes
* Add sightings
Align MISP distribution and TLP values with your organization's sharing policy
before publishing indicators.
# Integration Operations
Source: https://docs.casebender.com/en/settings/integrations/operations
Monitor connector health, action outcomes, catalog versions, and credential rotation.
## Health tab
Open **Settings → Integrations → Health** to review the integration execution
plane. The Health tab summarizes:
* Enabled and unhealthy connections
* Connector action success and failure counts
* Recent execution latency and errors
* Credential health and rotation state
* Installed catalog size and connector maturity
* Jira outbox and webhook status counts for the last 24 hours
* Jira policy version, sync health, and recent recoverable failures
Select **Manage** on a Connections row, then **Test connection**, to run the
connector's declared health action. Testing uses the same host allowlist,
timeout, response limit, tenant isolation, and redaction controls as production
execution.
## Jira recovery
Jira outbound automation is recorded in a durable tenant-scoped outbox.
**Retry now** makes an eligible failed event immediately available without
changing its remaining attempt budget. **Replay** moves a dead-letter event back
to pending and grants the displayed additional attempts. Both actions preserve
the event's original policy snapshot, payload, correlation context, and
idempotency key, and both write an immutable unified audit record.
Confirm the mapping or provider problem is resolved before recovery. Recovery
controls are available only to users with existing integration-management
permission, and event identifiers are resolved inside the active organization.
Jira webhook processing uses an expiring ownership lease. **Release lease** is
available only when a `PROCESSING` receipt is stale. Releasing it marks the
expired claim failed so the existing queue retry or Jira redelivery can claim
the receipt. It does not republish or reconstruct the webhook: raw inbound
payloads are intentionally not persisted.
Use Jira's delivery log to redeliver a failed webhook when the worker queue no
longer has the original message.
## Connector maturity
Catalog entries can be **certified**, **supported**, **community**, **private**,
or **deprecated**. Maturity is version-specific. Casebender pins the connector
version when creating a connection.
## Troubleshooting
1. Confirm both `workflow-processor` and `connector-worker` are healthy.
2. Confirm they use the same Redis action and result queue names.
3. Check that the connection is enabled and visible to the workflow's
organization.
4. Verify that a live credential is bound and that its host allowlist covers the
configured base URL.
5. Review the connector worker error and circuit-breaker state.
6. Rotate an expired credential, then retest the connection.
7. For Jira, inspect failed/dead-letter automation and failed, rejected, or
stale webhook receipts. Resolve the cause before using recovery.
Connector responses are bounded and secret fields are redacted before outputs
are persisted. Use vendor-side request identifiers for deeper investigation;
do not enable raw secret or response-body logging.
For emergency rollback, disable the connection to stop new workflow and
automation use. Disable individual Jira policy controls when only one event
class must stop. Restoring previous mappings publishes a new policy version;
historical outbox events remain immutable.
# Palo Alto Networks
Source: https://docs.casebender.com/en/settings/integrations/paloalto
Run governed Panorama and Strata response actions from CaseBender.
## Overview
The Palo Alto Networks connector retrieves system context and performs
policy-controlled IP or domain blocking through Panorama or Strata Cloud
Manager.
## Configure
Create a dedicated administrator profile limited to the device groups and
policy objects CaseBender may manage.
In **Settings → Integrations**, select **Add integration**, choose **Palo Alto Networks**, enter the
management URL and API key, and explicitly allow the management hostname.
Bind the credential to the management endpoint and verify system
information can be read.
## Available actions
* Test the connection and retrieve system information
* Block an IP address
* Block a domain
Blocking actions require an immediately preceding approved workflow gate.
Review device group and address-group inputs before approval.
# Proofpoint TAP
Source: https://docs.casebender.com/en/settings/integrations/proofpoint
Ingest Proofpoint Targeted Attack Protection threat events into CaseBender by automatic polling (pull) using the SIEM API.
## Overview
The Proofpoint integration (**INT-012**) ingests email-security threat events (malicious
messages and clicks) from Proofpoint Targeted Attack Protection (TAP) into CaseBender and turns
them into alerts (and optionally cases).
**Recommended: enable Automatic polling.** CaseBender pulls new threat events
directly from the Proofpoint TAP SIEM API on a schedule — no inbound endpoint
is required. See [Automatic polling](#inbound-automatic-polling-recommended).
Polling uses the **Proofpoint TAP SIEM API**, authenticated with a **service
principal + secret** (HTTP Basic).
## Capabilities
| Capability | Direction | Description |
| ------------------------- | --------- | ----------------------------------------------------------------------------- |
| **Threat polling (pull)** | Inbound | CaseBender polls the TAP SIEM API on a schedule and ingests new threat events |
| Message + click events | Inbound | Blocked/delivered messages and blocked/permitted clicks are ingested |
| Observable extraction | Inbound | Senders, recipients, URLs, and threat indicators |
| Classification tagging | Inbound | Threat type and classification become tags |
## Prerequisites
In the Proofpoint TAP dashboard, go to **Settings → Connected Applications** and create a
**Service Principal**. Copy the **principal** and **secret**.
The CaseBender poller must reach `https://tap-api-v2.proofpoint.com`.
## Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **Proofpoint** from the
**Email Security** category.
| Field | Description |
| ------------------ | ----------------------------------------------- |
| Service Principal | TAP SIEM API service principal |
| Secret | TAP SIEM API secret |
| API URL (optional) | Defaults to `https://tap-api-v2.proofpoint.com` |
| Option | Effect |
| ------------------------ | ---------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of threat events |
| `pollingIntervalMinutes` | How often to poll (default `5`; keep at/below 5) |
| `pollMaxItemsPerRun` | Safety cap on items ingested per run (default `500`) |
| Option | Effect |
| -------------------- | ---------------------------------------------------------------------- |
| `autoCreateCases` | Promote each threat event to a **Case** (deduped by threat/message ID) |
| `minSeverityForCase` | Only auto-create cases at/above this severity |
## Inbound (automatic polling, recommended)
On each interval, CaseBender requests all threat events since the last cursor. The SIEM API
serves at most the **last 12 hours** in **one-hour windows**, so CaseBender clamps the request
window accordingly and uses the API's `queryEndTime` as the next cursor.
Events are **deduplicated by `threatID`/`messageID`**, so overlapping polling windows never
create duplicates.
Each event is normalized into a CaseBender alert with sender/recipient/URL observables and
classification tags.
Because the SIEM API only serves the last 12 hours, keep polling enabled continuously and set a
short interval (≤ 5 minutes). If the poller is offline for more than 12 hours, events older than
that window cannot be retrieved retroactively.
## Security considerations
* **Secret handling** — the service principal secret is stored in the integration settings;
rotate on your organization's schedule.
* **Network** — restrict egress to `https://tap-api-v2.proofpoint.com`.
## Troubleshooting
Confirm the service principal + secret are valid and that TAP recorded threat activity in the
last hour. Keep the interval at/below 5 minutes.
**Make sure all CaseBender services are running** — with Docker, `docker compose ps` should
show the `worker` and `misp-processor` services `Up`.
The service principal or secret is incorrect, or the connected application was removed in the
TAP dashboard.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [Proofpoint TAP SIEM API](https://help.proofpoint.com/Threat_Insight_Dashboard/API_Documentation/SIEM_API)
# ServiceNow
Source: https://docs.casebender.com/en/settings/integrations/servicenow
Connect CaseBender to ServiceNow ITSM and CMDB with governed credentials and workflow actions.
## Overview
The ServiceNow connector creates and updates incidents, adds work notes, and
looks up CMDB records from CaseBender workflows.
## Configure
Open **Settings → Integrations**, select **Add integration**, choose **ServiceNow**, then select Basic
authentication or OAuth client credentials. Enter the instance URL and the
required account or application credentials.
Bind the credential to the ServiceNow instance URL. Add the private hostname
to the credential allowlist when the instance is available only on-prem.
Test the connection, then select it from a **Connector Action** workflow
node.
## Available actions
* Test the connection
* Create and update incidents
* Add work notes
* Look up CMDB configuration items
Use a dedicated least-privilege ServiceNow account. Secrets are encrypted and
are not returned after creation.
# Slack
Source: https://docs.casebender.com/en/settings/integrations/slack
Connect Slack for notifications, channel operations, and approval workflows.
## Overview
The Slack connector posts messages, lists channels, and creates channels from
CaseBender workflows. It supports bot tokens and authorization-code OAuth.
## Configure with OAuth
Configure the CaseBender callback URL shown by **Settings → Integrations → Add integration**
and grant only the scopes required by your workflows.
Choose **Slack OAuth App**, enter the client ID and secret, then select
**Connect with OAuth**. CaseBender verifies signed state and PKCE before
storing the returned token.
Bind the OAuth credential to `https://slack.com` and run the connection
test.
## Available actions
* Test authentication
* List channels
* Post messages and Block Kit payloads
* Create channels
OAuth client secrets and access tokens are encrypted and never displayed after
the authorization flow completes.
# Splunk
Source: https://docs.casebender.com/en/settings/integrations/splunk
Bi-directional integration between CaseBender and Splunk (Enterprise Security) for notable/alert ingestion, HEC audit forwarding, and notable close-out sync.
## Overview
The Splunk integration (**INT-001**) provides **bi-directional** synchronization between
CaseBender and Splunk, including **Splunk Enterprise Security (ES)** notable events.
Splunk notables and alerts are ingested into CaseBender — either **pulled
automatically** on a schedule via the ES REST search API, or **pushed** from a
Splunk alert action / webhook — then normalized, enriched with observables,
and turned into alerts (or cases).
Case lifecycle events are forwarded to a Splunk index via **HEC**, and when a
linked case is closed CaseBender can **close the originating ES notable** via
the REST API with an audit comment.
**Two inbound paths.** Use **alert-action / webhook (push)** if you already
build Splunk alerts, or **automatic polling (pull)** if you'd rather have
CaseBender run a saved search on a schedule. Polling requires the Enterprise
Security REST connection; the webhook path does not.
Outbound HEC uses the **HTTP Event Collector** (default `/services/collector/event`,
usually port `8088`). Notable pull and close-out use the **management REST API**
(usually port `8089`). On-prem Splunk commonly uses **self-signed certificates** on
both — set **Verify SSL** off if needed (see below).
## Capabilities
| Capability | Direction | Description |
| ------------------------------ | --------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Notable polling (pull)** | Inbound | CaseBender runs your SPL on a schedule via the ES REST search API and ingests results automatically — no Splunk-side setup |
| Alert ingestion (push) | Inbound | Splunk alert actions / webhooks post payloads that are normalized into CaseBender alerts |
| Observable extraction | Inbound | `src`/`dest`/`user` (and `*_ip`) fields become IP / hostname / user observables |
| Asset extraction | Inbound | `host` (and non-IP `dest`) become host assets |
| Auto-create cases | Inbound | Ingested records can be promoted to Cases automatically (deduped by notable ID) |
| HEC audit forwarding | Outbound | Case create/update/close and alert promotion are logged to a Splunk index |
| Notable close-out (write-back) | Outbound | On case close, the originating ES notable is set to Closed with a comment via `notable_update` |
| Connection test | Outbound | Sends a test event to the HEC endpoint |
## Prerequisites
A Splunk deployment. For notable pull/close-out you need **Splunk Enterprise
Security** and a role with the `edit_notable_events` capability. For HEC
forwarding you need an **HTTP Event Collector** token.
The CaseBender deployment (and the background poller service, for polling)
must be able to reach your Splunk **HEC** endpoint (e.g. `:8088`) and, for
REST features, the **management** endpoint (e.g. `:8089`).
You must be able to create and manage integrations in **Settings → Integrations**.
## Part A — Prepare Splunk
In Splunk, go to **Settings → Data inputs → HTTP Event Collector → New Token**.
Enable HEC globally if it isn't already, choose (or create) a target index, and
copy the token value.
For notable **polling** and **close-out**, create a Splunk **authentication
token** under **Settings → Tokens** (or use a service account for Basic auth).
The associated role needs `edit_notable_events` to close notables and search
access to your notable index.
## Part B — Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **Splunk** from the
**SIEM** category.
Set `purpose` to **Inbound**, **Outbound**, or **Bidirectional** to show the
relevant configuration cards.
Copy the **Webhook URL** and generate an **API key** (prefixed `cbr_splunk_`;
legacy `sk_splunk_` keys are still accepted).
In Splunk, add a **Webhook** alert action that posts to the URL with header
`Authorization: Bearer `.
In the **Enterprise Security REST API** card, enter the management URL (e.g.
`https://splunk:8089`) and credentials:
| Field | Description |
| ------------------------------- | ----------------------------------------------- |
| `restUrl` | Splunk management URI (usually port 8089) |
| `restAuthType` | `token` (bearer) or `basic` (username/password) |
| `restToken` | Splunk authentication token (bearer) |
| `restUsername` / `restPassword` | Basic-auth credentials |
This connection powers both notable **polling** and **close-out**.
In the **Automatic polling** card, turn on **Enable automatic polling** and set:
| Option | Effect |
| ----------------------------- | ------------------------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled pulling of Splunk results |
| `searchQuery` | SPL run each interval, e.g. `` search `notable` `` (must start with `search` or `\|`) |
| `pollingIntervalMinutes` | How often to poll (default `5`, range 1–1440) |
| `pollingInitialLookbackHours` | On first run, import results from within this window (default `24`, range 1–168) |
See [Automatic polling](#inbound-automatic-polling) for how it works.
In the **Outbound** card, enter the HEC URL, token, and index, then enable:
| Option | Effect |
| ------------------------- | ------------------------------------------------------------------------------ |
| `syncCaseUpdates` | Forward `case_created` / `case_updated` / `alert_promoted` audit events to HEC |
| `syncCaseClose` | Forward a `case_closed` audit event to HEC |
| `closeNotableOnCaseClose` | Close the originating ES **notable** via REST when a linked case is closed |
| `autoCreateCases` | Promote each ingested Splunk record to a **Case** automatically |
Use **Test Connection** to send a test event to the HEC endpoint. If your
Splunk uses a self-signed certificate, turn **Verify SSL** off.
## Inbound (automatic polling)
With **Automatic polling** enabled, CaseBender periodically runs your SPL through the
Enterprise Security REST search API and ingests the results on its own — **no Splunk-side
alert action or webhook is required**.
### How it works
On each interval (`pollingIntervalMinutes`), CaseBender runs `searchQuery` over the window
since the last cursor via the streaming export endpoint:
```
POST https://:8089/services/search/jobs/export
search=&earliest_time=&latest_time=now&output_mode=json
```
On the very first run there is no cursor, so results from within
`pollingInitialLookbackHours` are imported.
CaseBender advances a per-integration cursor to the newest result `_time` it has seen, so
each run only fetches new activity. Results are also **deduplicated by notable `event_id`**
(falling back to the search `sid`), so a notable is never ingested twice — even if the
polling window overlaps.
Each result row is normalized into a CaseBender alert — mapping severity from `urgency`,
building the title/description, and extracting observables and host assets. The notable
`event_id` is stamped onto the alert so outbound close-out can find it later.
With **`autoCreateCases` enabled**, each polled notable becomes a **Case** automatically
(deduplicated by notable ID) — this matches the "pull notable → work it as a case" flow.
With it disabled, results land in the **Alerts** inbox for manual promotion. Either way the
Splunk link is preserved so closing the case can close the notable.
Polling runs in CaseBender's background poller service. Ensure that service can reach your
Splunk management endpoint (directly or via your configured proxy). Internal Splunk hosts
should be listed in `NO_PROXY` on proxy-only networks.
## Inbound (webhook / push)
As an alternative (or in addition) to polling, a Splunk **alert action** (or any webhook
sender) can push search results to the CaseBender ingestion endpoint.
### Endpoint
```
POST https:///api/v1/ingest/splunk
```
Requests are authenticated with an integration **API key** passed as
`Authorization: Bearer ` (the `x-api-key` header is also accepted). Splunk webhook API
keys are minted with the prefix `cbr_splunk_`. Legacy `sk_splunk_` keys are still accepted.
### Payload example
Splunk's webhook alert action posts a `result` object plus search metadata:
```bash theme={null}
curl -X POST "https:///api/v1/ingest/splunk" \
-H "Authorization: Bearer cbr_splunk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"sid": "scheduler__admin__search__RMD5...",
"search_name": "Threat - Brute Force Access - Rule",
"results_link": "https://splunk.example.com/app/search/...",
"app": "SplunkEnterpriseSecuritySuite",
"result": {
"event_id": "A1B2C3D4-...",
"rule_title": "Brute Force Access Behavior Detected",
"urgency": "high",
"security_domain": "access",
"src": "10.0.0.5",
"dest": "10.0.0.20",
"user": "jdoe"
}
}'
```
A successful request returns HTTP `202 Accepted`:
```json theme={null}
{ "success": true, "messageId": "..." }
```
### Processing pipeline
Production gateways (installer nginx, Kubernetes HTTPRoute, OpenShift) send
`POST /api/v1/ingest/splunk` to the ingestion service. The Next.js
`/api/v1/ingest/[source]` route is local/dev only.
The ingestion service authenticates the API key, validates the payload, and publishes the
record to the processing queue.
The Splunk processor normalizes the record into a CaseBender alert — mapping severity,
building the title/description, and extracting observables and host assets.
### Data mapping reference
**Severity mapping** (Splunk `urgency` → CaseBender 1–4):
| Splunk urgency | CaseBender severity |
| ----------------------- | ------------------- |
| `critical` | 4 |
| `high` | 3 |
| `medium` | 2 |
| `low` / `informational` | 1 |
**Observable / asset extraction:**
| Splunk field | Observable / asset |
| ------------------ | ----------------------------------- |
| `src` / `src_ip` | `ip` or `hostname` observable (IOC) |
| `dest` / `dest_ip` | `ip` or `hostname` observable |
| `user` | `user` observable |
| `host` | host asset |
**Title** is built from `rule_title` → `search_name` → `alert_name` → `signature` →
`message`. **Tags** applied on ingest include `splunk`, `siem`, `notable` (for ES notables),
`domain:`, and `app:`. Ingested records default to **TLP:2** and
**PAP:2**.
## Outbound: HEC audit forwarding
When enabled with `syncCaseUpdates` / `syncCaseClose`, CaseBender posts JSON audit events to
your HEC endpoint so case activity is searchable in Splunk:
| Event | HEC `action` | Gate |
| -------------- | ------------------------ | ----------------- |
| Case created | `case_created` | `syncCaseUpdates` |
| Case updated | `case_updated` | `syncCaseUpdates` |
| Alert promoted | `alert_promoted_to_case` | `syncCaseUpdates` |
| Case closed | `case_closed` | `syncCaseClose` |
Events are sent with `source: casebender:case` (or `casebender:alert`) and `sourcetype: _json`
to the configured index.
## Outbound: Closing the Splunk notable (write-back)
When a case is closed in CaseBender, the `case_closed` event is dispatched to the Splunk
handler. If the case is linked to a Splunk notable **and** `closeNotableOnCaseClose` is on,
CaseBender closes the notable through the ES REST API.
### How the linked notable is resolved
The ingest pipeline stamps `splunkEventId` (the notable `event_id`) and the ingesting
integration ID onto each Splunk alert's `customFields`. On case close, the handler collects
those event IDs from the alerts linked to the case, so a case promoted from a polled or
webhook notable resolves automatically — regardless of how it was created.
### What is sent
CaseBender calls the ES `notable_update` endpoint:
```
POST https://:8089/services/notable_update
ruleUIDs=["", ...]&status=&comment=&output_mode=json
```
* `status` defaults to **5 (Closed)** and is configurable via `notableStatusOnClose`.
* `comment` is: `Case closed in CaseBender with resolution: `.
The outcome (notables closed, or an error) is written to the case timeline so analysts can
confirm the sync.
`syncCaseClose` (HEC audit event) and `closeNotableOnCaseClose` (REST notable write-back)
are independent per-integration toggles. Notable write-back requires the Enterprise Security
REST connection and a role with the `edit_notable_events` capability.
## Security considerations
* **Token handling** — HEC tokens and REST tokens/passwords are stored in the integration
settings; rotate them on your organization's schedule and update the integration when you do.
* **Least privilege** — the REST role only needs search access to your notable index and
`edit_notable_events`. HEC tokens should target a dedicated index.
* **Webhook keys** — treat the `cbr_splunk_` API key as a secret. Rotate it if exposed and
update the Splunk alert action. Legacy `sk_splunk_` keys remain valid until rotated.
* **TLS** — prefer trusted certificates. If you must use self-signed certs (common on-prem),
**Verify SSL** can be turned off; the connection is still encrypted but the certificate is
not validated. Restrict egress to your Splunk HEC and management endpoints.
## Troubleshooting
Confirm the HEC URL and token, that HEC is enabled, and that CaseBender can reach the HEC
port (usually `8088`). If Splunk uses a self-signed certificate, turn **Verify SSL** off —
otherwise the request fails with a certificate error.
The `Authorization: Bearer` (or `x-api-key`) header is missing or invalid. Confirm you are
sending the `cbr_splunk_` (or legacy `sk_splunk_`) key that matches the integration's configured webhook API key.
Confirm **Enable automatic polling** is on, the **ES REST** connection is filled in, and a
**search query** is set. Verify the role can run the search and reach the management port
(usually `8089`), and that there are results newer than the cursor. On first run only
results within `pollingInitialLookbackHours` are imported. Check the integration's last
sync status for the specific error.
**Make sure all CaseBender services are running.** Notables are fetched by the background
poller and turned into alerts (and optionally cases) by the background **worker**. If the
worker isn't running, notables are fetched but never show up. With Docker, run
`docker compose ps` and confirm the `worker` and `misp-processor` services are `Up`; if not,
run `docker compose up -d`. The standard installer and quickstart set everything up
automatically — you do not need to configure any queue or Redis settings yourself.
Ensure `closeNotableOnCaseClose` is on and the **ES REST** connection is configured with a
role that has `edit_notable_events`. The case must be linked to a Splunk notable — closing
a case promoted from a polled/webhook notable resolves the link automatically. Check the
case timeline for the sync result.
A `403` means the REST role lacks the `edit_notable_events` capability. A `404` usually
means the URL isn't the Enterprise Security management endpoint — confirm `restUrl` points
at Splunk's management port with ES installed.
On proxy-only networks, add your internal Splunk host to `NO_PROXY` so the connection goes
direct, and turn **Verify SSL** off if the cert is self-signed.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [Splunk HTTP Event Collector](https://docs.splunk.com/Documentation/Splunk/latest/Data/UsetheHTTPEventCollector)
* [Splunk ES notable event actions](https://docs.splunk.com/Documentation/ES/latest/User/Triagenotableevents)
# Tenable.io
Source: https://docs.casebender.com/en/settings/integrations/tenable
Ingest Tenable.io vulnerability findings into CaseBender by automatic polling (pull) using the Vulnerability Export API.
## Overview
The Tenable.io integration (**INT-003**) ingests vulnerability findings into CaseBender,
enriches them with CVSS-based severity and CVE observables, and turns them into alerts (and
optionally cases).
**Recommended: enable Automatic polling.** CaseBender pulls new vulnerabilities
directly from Tenable.io on a schedule using the Vulnerability Export API — no
inbound endpoint is required. See
[Automatic polling](#inbound-automatic-polling-recommended).
Polling uses the **Tenable.io Vulnerability Export API**, authenticated with an
**API key pair** (access key + secret key).
## Capabilities
| Capability | Direction | Description |
| -------------------------------- | --------- | ------------------------------------------------------------------------- |
| **Vulnerability polling (pull)** | Inbound | CaseBender exports vulnerabilities on a schedule and ingests new findings |
| Observable extraction | Inbound | Host IPs, hostnames, and CVEs |
| CVSS severity mapping | Inbound | Findings are mapped to CaseBender severity from CVSS |
| Severity threshold | Inbound | Optionally pull only findings at/above a minimum severity |
## Prerequisites
In Tenable.io, go to **Settings → My Account → API Keys** and generate a key pair. Copy the
**Access Key** and **Secret Key**.
The CaseBender poller must reach `https://cloud.tenable.com` (or your private Tenable.io
region URL).
## Configure the integration in CaseBender
Go to **Settings → Integrations → Create**, then choose **Tenable.io** from the
**Vulnerability Management** category.
| Field | Description |
| --------------------------- | -------------------------------------------------------------------------------------- |
| Access Key | Tenable.io API access key |
| Secret Key | Tenable.io API secret key |
| API URL (optional) | Defaults to `https://cloud.tenable.com` |
| Minimum severity (optional) | One of `info`, `low`, `medium`, `high`, `critical` — only findings at/above are pulled |
| Option | Effect |
| ----------------------------- | --------------------------------------------------------------------------------- |
| `pollingEnabled` | Turn on scheduled export + ingestion |
| `pollingIntervalMinutes` | How often to poll (default `15`; exports are asynchronous, so 15+ is recommended) |
| `pollingInitialLookbackHours` | On first run, import findings updated within this window (default `24`) |
| `pollMaxItemsPerRun` | Safety cap on items ingested per run (default `500`) |
| Option | Effect |
| -------------------- | -------------------------------------------------------------- |
| `autoCreateCases` | Promote each finding to a **Case** (deduped by asset + plugin) |
| `minSeverityForCase` | Only auto-create cases at/above this severity |
## Inbound (automatic polling, recommended)
Tenable exposes incremental vulnerability data through an **asynchronous export job**. CaseBender
manages that flow automatically:
On each interval, CaseBender requests an export of `OPEN`/`REOPENED` vulnerabilities updated
since the last cursor (optionally severity-filtered). On first run, the window is
`pollingInitialLookbackHours`.
CaseBender waits (bounded) for the export to finish and downloads its chunks. If the export
is still building when the in-tick budget elapses, its ID is saved and the next tick resumes
it — no data is lost.
After a completed export, the cursor advances to the run time. Findings are **deduplicated by
`asset.uuid` + `plugin.id`**, so overlapping windows never create duplicates.
Because exports are asynchronous, findings may appear a few minutes after they are updated in
Tenable. This is expected for vulnerability data and controlled by `pollingIntervalMinutes`.
## Security considerations
* **Secret handling** — the API keys are stored in the integration settings; rotate on your
organization's schedule.
* **Least privilege** — use keys tied to a user account with read access to vulnerabilities.
* **Network** — restrict egress to your Tenable.io region URL.
## Troubleshooting
Confirm the access/secret keys are valid and there are `OPEN`/`REOPENED` findings updated
since the cursor. Exports take time; allow at least one full interval. Lower the `Minimum
severity` if it filters everything out.
**Make sure all CaseBender services are running** — with Docker, `docker compose ps` should
show the `worker` and `misp-processor` services `Up`.
A `Tenable export … failed` error indicates the export job errored server-side. It will be
retried on the next interval. Verify the keys have vulnerability export permission.
## Related documentation
* [Integrations overview](./introduction.mdx)
* [Tenable Developer Portal](https://developer.tenable.com/)
# Settings
Source: https://docs.casebender.com/en/settings/introduction
Manage your CaseBender account, organization, security operations configuration, integrations, and platform preferences.
## Overview
Settings combines personal account controls with organization and platform administration. The navigation items you see depend on your role, organization, permissions, and enabled platform capabilities.
## Account settings
Manage your name, avatar, password, and multi-factor authentication.
Configure organizational structure, governance, and administrators.
Manage teams, classification, membership, escalation, and shared notification channels.
Review users and administer invitations, roles, and team assignments.
Review your inbox and configure personal notification preferences.
Create scoped credentials and manage their operational lifecycle.
## Platform settings
Connect CaseBender with security, collaboration, and infrastructure services.
Build automated workflows for security operations.
Configure supported AI capabilities and providers.
Define structured fields for supported entities.
Manage the observable types used during investigations.
Maintain MITRE ATT\&CK-aligned attack-pattern data.
Configure the statuses used throughout the alert lifecycle.
Configure the statuses used throughout the case lifecycle.
Create reusable structures for supported records.
Customize the visual identity of your CaseBender instance.
Limit inactive and total session duration for each organization.
View your plan, seats, Installation ID, and apply a paid license key.
## Access control
* Personal settings are available to authenticated users.
* Organization and team management require scoped administrative permissions.
* Sensitive operations can require step-up authentication.
* Read-only roles can inspect permitted settings without changing them.
* Server-side authorization remains authoritative even when the interface hides an action.
See [Access Control](/en/security/access-control) for the role and permission model.
## Change-management recommendations
1. **Use least privilege.** Grant only the permissions required for each administrator and integration.
2. **Test safely.** Validate workflow, integration, notification, and governance changes outside production when possible.
3. **Document ownership.** Record who owns each organization, team, integration, and API credential.
4. **Review regularly.** Audit memberships, elevated roles, credentials, notification destinations, and retention settings.
5. **Plan rollback.** Understand how to reverse a configuration change before applying it to production.
Settings can affect access, data handling, automation, and incident delivery. Coordinate high-impact changes with the relevant security, privacy, legal, and platform owners.
# License
Source: https://docs.casebender.com/en/settings/license
View your CaseBender plan, seats, and Installation ID, and apply a paid license key.
A new on-premises installation starts on the **Community** plan. That plan is issued locally during first boot. You do not need a key from CaseBender to begin using the product.
Paid plans (Pro and Enterprise) are issued by CaseBender against this appliance's **Installation ID**. Open **Settings → License** as a Super Admin or Organization Admin.
## What the License page shows
* Current plan (Community, Pro, or Enterprise)
* Seat count
* Expiration date, when the plan has a term
* **Installation ID**, a stable public identifier such as `CBI-XXXX-XXXX-XXXX-XXXX`
* **Contact sales**, which opens a mail draft that already includes the Installation ID
The Installation ID identifies this deployment. It is not a secret and is safe to copy into a license request. Settings never displays `LICENSE_SECRET_KEY`. Do not send that value to CaseBender.
## Request a paid license
Open **Settings → License** and copy the Installation ID. Operators can also print it from the installation host:
```bash theme={null}
./casebender license
```
The command prints only the Installation ID. It never prints `LICENSE_SECRET_KEY`.
Use **Contact sales** on the License page, or email CaseBender with the Installation ID, the plan you need, the number of seats, and the term.
Select **Upgrade to Pro** or **Update your license**, paste the full key into the dialog, and save. The same field accepts a new paid key and a key you already applied on this installation.
The key is bound to this Installation ID. A key issued for a different appliance will not activate here.
## Community plan
Community includes **1** user and does not expire. Invite and account-creation paths enforce that seat limit on the server. To add analysts, request a paid key.
## Paid plans
A paid key declares the seat count and the expiration date. CaseBender re-reads the key on the appliance; the date stored in the database is not the source of truth.
* While the term is valid, Super Admins and Organization Admins can change the deployment as usual.
* After the term ends, CaseBender keeps a short grace period so you can apply a renewal key without interrupting investigations.
* When grace ends, the appliance becomes **read-only** until you apply a renewed key. Existing cases remain visible; writes are blocked.
Applying a key does not require outbound access to CaseBender. Air-gapped installations can paste a key received over an approved offline channel.
## After you apply a key
* Keep the Installation ID with your runbooks. It does not rotate when Community is refreshed or when you upgrade the images.
* Back up `.env` with the rest of the installation. New installs write `CASEBENDER_INSTALLATION_ID` there so web, API, and worker share the same ID.
* Rebuilding the appliance on a new host creates a **new** Installation ID. Ask CaseBender for a key bound to the new ID; do not reuse a key from the previous host.
Do not paste `.env`, `LICENSE_SECRET_KEY`, database URLs, or other secrets into a license request. The Installation ID is the only identifier CaseBender needs to issue a paid key.
## Related guides
* [Members](/en/settings/account/members) — inviting users within the licensed seat count
* [First-run setup](/en/deployment/first-run-setup)
* [Upgrading CaseBender](/en/deployment/upgrading)
# Observable Types
Source: https://docs.casebender.com/en/settings/observable-types/introduction
Configure and manage observable types to categorize and track different types of indicators in your threat intelligence.
## Overview
The Observable Types section allows you to define and manage different types of observables that can be tracked in your threat intelligence operations. These types help categorize various indicators such as IP addresses, domains, file hashes, and other digital artifacts that you monitor.
## Managing Observable Types
### Creating a New Type
Click the "Create" button to add a new observable type:
Configure the following settings:
* Type name
* Description
* Category
* Validation rules
* Display format
## Common Observable Types
### Network Indicators
* IP Address
* IPv4 format
* IPv6 format
* CIDR notation
* Domain Names
* Fully Qualified Domain Names (FQDN)
* Wildcards
* IDN support
* URLs
* Web addresses
* URI patterns
* Protocol specifications
### File Indicators
* File Hashes
* MD5
* SHA-1
* SHA-256
* SHA-512
* File Names
* Extensions
* Patterns
* Regular expressions
* File Paths
* Directory structures
* Path patterns
### System Indicators
* Registry Keys
* Windows registry paths
* Value names
* Data types
* Process Names
* Executable names
* Command lines
* Process patterns
* Service Names
* Windows services
* Unix daemons
* Service patterns
### Communication Indicators
* Email Addresses
* Address formats
* Domain validation
* Pattern matching
* User Accounts
* Usernames
* Account IDs
* Platform identifiers
* Communication Protocols
* Port numbers
* Protocol identifiers
* Service definitions
## Best Practices
### Type Definition
* Use clear, descriptive names
* Provide detailed descriptions
* Set appropriate validation rules
* Include example values
### Organization
* Group related types
* Maintain consistent naming
* Use categories effectively
* Consider type relationships
### Validation Rules
* Define format requirements
* Set value constraints
* Configure pattern matching
* Implement data validation
### Maintenance
* Review type usage
* Update definitions
* Document changes
* Monitor effectiveness
## Using Observable Types
### In Cases
* Threat indicators
* IOC tracking
* Evidence collection
* Pattern matching
### In Analysis
* Indicator correlation
* Pattern detection
* Threat hunting
* Intelligence gathering
### In Reports
* Indicator statistics
* Type distribution
* Trend analysis
* Intelligence reporting
## Related Documentation
* [Case Management](../../cases/introduction.mdx)
# Templates
Source: https://docs.casebender.com/en/settings/templates/introduction
Create and manage templates to standardize case creation and response procedures in your security operations.
## Overview
The Templates section allows you to create and manage predefined templates for various aspects of your security operations. Templates help ensure consistency, save time, and standardize processes across your organization by providing ready-to-use configurations for cases, tasks, and workflows.
## Managing Templates
### Creating a New Template
Click the "Create" button to start creating a new template:
Configure the basic template information:
* Template name
* Description
* Category
* Type (Case/Task/Workflow)
* Access permissions
### Configuring Template Details
Define the comprehensive configuration for your template:
Specify detailed settings:
* Content structure
* Default values
* Required fields
* Automation rules
* Team assignments
### Template Management
View and manage your configured templates:
The template list displays:
* Template name
* Description
* Category
* Type
* Usage count
* Last modified
* Actions
## Template Types
### Case Templates
* Incident Response
* Threat Hunting
* Vulnerability Management
* Security Assessment
* Compliance Review
### Task Templates
* Investigation Steps
* Evidence Collection
* Analysis Procedures
* Remediation Actions
* Status Updates
### Workflow Templates
* Alert Triage
* Incident Response
* Threat Investigation
* Compliance Checks
* Regular Assessments
## Template Components
### Content Structure
* Sections and subsections
* Field definitions
* Dynamic content
* Variable placeholders
### Default Values
* Predefined fields
* Standard responses
* Common settings
* Initial assignments
### Automation Rules
* Automatic field population
* Conditional logic
* Required actions
* Workflow triggers
## Best Practices
### Template Design
* Clear organization
* Consistent structure
* Comprehensive coverage
* User-friendly format
### Content Management
* Regular updates
* Version control
* Change documentation
* Usage tracking
### Team Usage
* Training materials
* Usage guidelines
* Access controls
* Feedback collection
### Quality Assurance
* Regular reviews
* Validation checks
* Effectiveness monitoring
* User feedback
## Using Templates
### In Case Management
* Quick case creation
* Standardized responses
* Consistent documentation
* Efficient handling
### In Task Management
* Structured workflows
* Clear procedures
* Repeatable processes
* Quality assurance
### In Reporting
* Template usage metrics
* Efficiency analysis
* Process improvements
* Success tracking
## Related Documentation
* [Case Management](../../cases/introduction.mdx)
* [Task Management](../../tasks/introduction.mdx)
# Connector Actions
Source: https://docs.casebender.com/en/settings/workflows/connector-actions
Use schema-driven installed integration actions in durable workflows.
## Add a connector action
1. Open a workflow and add **Installed Integrations → Connector Action**.
2. Select a connector, action, and approved connection.
3. Pin the connector version.
4. Map action inputs from the trigger context or earlier step outputs.
5. Use **Simulate** to validate request rendering without executing a
destructive operation.
Connector action jobs are durable. The workflow processor records the step,
dispatches it to the dedicated connector worker, and advances the workflow only
after the result is received.
## Expressions and outputs
Inputs support the same workflow expression context as other actions. Prior
connector outputs are available under `steps`:
```text theme={null}
{{ steps.lookup-alert.output.id }}
```
Only the connector manifest's projected output is persisted. Authentication
headers, credential fields, and configured secret paths are redacted.
## Destructive actions
Actions marked destructive must immediately follow an approved workflow gate;
execution is rejected otherwise. Simulation
does not send the vendor request. Production deployments force
`CONNECTOR_MOCK_DESTRUCTIVE=0`; use test credentials and vendor sandboxes for
validation.
## Version upgrades
Changing a connector version is an explicit workflow edit. Re-run simulation
and publish a new workflow version after reviewing any input or output schema
changes.
# Workflows
Source: https://docs.casebender.com/en/settings/workflows/introduction
Create and manage automated workflows to streamline your case management processes in CaseBender.
## Overview
The Workflow Settings section allows you to create automated workflows that execute actions based on specific triggers in your CaseBender instance. This guide will walk you through the process of setting up and configuring workflows.
## Creating a New Workflow
### Step 1: Basic Configuration
Start by clicking the "Create" button and filling out the basic workflow information:
### Step 2: Workflow Details
Configure the detailed settings for your workflow:
Fill out the required information such as:
* Workflow name
* Description
* Priority level
* Execution settings
### Step 3: Organization Settings
Specify which organizations can access and use this workflow:
* Select applicable organizations
* Configure organization-specific settings
* Set access permissions
## Configuring Workflow Logic
### Step 1: Select Trigger
Choose the event that will initiate your workflow:
Available triggers may include:
* Case creation or updates
* Task assignments
* Status changes
* Custom events
### Step 2: Add Actions
Click the plus button on flow edges to add actions to your workflow:
### Step 3: Configure Action
Select and configure each action in your workflow:
### Step 4: Action Details
Provide detailed configuration for each action:
Configure settings such as:
* Action type specific parameters
* Conditional logic
* Input/output mapping
* Error handling
## Update Trigger Safety
Workflows triggered by case or alert updates include safeguards that prevent an
action from repeatedly triggering the same workflow:
* Updates that only change the internal `updatedAt` timestamp do not emit a new
workflow event.
* Assignment, status, severity, title, description, PAP, and case type actions
skip writes when the requested value is already present.
* A duplicate source event is processed only once.
* An update event is suppressed while the same workflow is already executing
for that case or alert.
* A per-entity circuit breaker suppresses excessive repeated executions.
Suppressed runs are retained in workflow execution history with a `suppressed`
status and loop-guard details. This provides an audit trail without executing
the workflow actions again.
### Circuit Breaker Configuration
The workflow processor uses safe defaults that can be adjusted with environment
variables:
* `WORKFLOW_LOOP_MAX_EXECUTIONS` — maximum executions for one workflow and
entity within the configured window. Default: `10`.
* `WORKFLOW_LOOP_WINDOW_MS` — circuit-breaker window in milliseconds. Default:
`60000`.
* `WORKFLOW_LOOP_ACTIVE_WINDOW_MS` — how long an unfinished execution is
considered active for recursive-event suppression. Default: `900000`.
Increasing these limits can allow a misconfigured update workflow to perform
repeated side effects. Test changes in a non-production environment and
monitor execution history after activation.
### Step 5: Review Workflow
Review your complete workflow with all configured actions:
## Best Practices
### Workflow Design
* Keep workflows focused and specific
* Use clear, descriptive names
* Document the purpose and expected outcomes
* Test workflows thoroughly before activation
* Avoid pairs of workflows that repeatedly reverse each other's changes
* Use conditions that describe the intended transition, not only the current state
### Performance Considerations
* Optimize action sequences
* Consider execution time and resources
* Monitor workflow performance
* Handle errors appropriately
* Investigate repeated `suppressed` executions before increasing safety limits
### Maintenance
* Regularly review and update workflows
* Monitor execution logs
* Keep documentation current
* Validate triggers and actions periodically
# Task Analytics
Source: https://docs.casebender.com/en/tasks/analytics
This guide covers the analytics and reporting features available for monitoring and improving task management efficiency.
## Overview
Task analytics provide insights into:
* Team performance
* Task efficiency
* Resource utilization
* Process bottlenecks
* Quality metrics
!\[Analytics Dashboard]
*Screenshot showing the main analytics dashboard*
## Key Metrics
### 1. Time-Based Metrics
Track time-related performance:
* Average completion time
* Time in each status
* Response time
* Overdue tasks
* Time estimates vs. actuals
### 2. Volume Metrics
Monitor task quantities:
* Total tasks
* Tasks by status
* Tasks by priority
* Tasks by type
* Tasks by assignee
### 3. Quality Metrics
Assess task quality:
* Completion rate
* Rework rate
* Review outcomes
* Error rates
* Customer satisfaction
### 4. Team Metrics
Evaluate team performance:
* Individual workload
* Team capacity
* Assignment balance
* Collaboration level
* Response times
## Dashboard Views
### 1. Executive Dashboard
High-level overview:
* Key performance indicators
* Trend analysis
* Strategic metrics
* Resource allocation
* Risk indicators
!\[Executive Dashboard]
*Screenshot showing executive-level metrics and KPIs*
### 2. Team Dashboard
Team-focused metrics:
* Team performance
* Workload distribution
* Collaboration patterns
* Efficiency metrics
* Quality indicators
!\[Team Dashboard]
*Screenshot showing team-level analytics*
### 3. Personal Dashboard
Individual metrics:
* Task progress
* Time tracking
* Due dates
* Priority queue
* Performance trends
!\[Personal Dashboard]
*Screenshot showing individual performance metrics*
## Reports
### Standard Reports
Pre-configured reports:
1. **Task Summary Report**
* Overall statistics
* Status distribution
* Priority breakdown
* Time analysis
2. **Team Performance Report**
* Individual metrics
* Team comparisons
* Workload analysis
* Efficiency scores
3. **Quality Report**
* Completion rates
* Review outcomes
* Error analysis
* Customer feedback
4. **Time Analysis Report**
* Duration metrics
* Delay analysis
* Response times
* Estimation accuracy
### Custom Reports
Build custom reports with:
* Selected metrics
* Custom filters
* Specific timeframes
* Chosen formats
* Automated delivery
!\[Custom Reports]
*Screenshot showing custom report builder*
## Analytics Features
### 1. Trend Analysis
Track changes over time:
* Historical comparisons
* Pattern recognition
* Seasonal variations
* Growth indicators
* Prediction models
### 2. Bottleneck Detection
Identify process issues:
* Status bottlenecks
* Resource constraints
* Delay patterns
* Process gaps
* Improvement areas
### 3. Resource Analysis
Monitor resource usage:
* Team utilization
* Skill distribution
* Capacity planning
* Workload balance
* Resource gaps
### 4. Performance Forecasting
Predict future trends:
* Completion estimates
* Resource needs
* Capacity requirements
* Risk assessment
* Growth planning
## Visualization Options
### Charts and Graphs
Various visualization types:
* Line charts
* Bar graphs
* Pie charts
* Heat maps
* Scatter plots
* Gantt charts
### Interactive Features
Dynamic analysis tools:
* Drill-down capability
* Custom filters
* Real-time updates
* Export options
* Sharing features
!\[Visualization Tools]
*Screenshot showing various chart types and interactive features*
## Best Practices
### 1. Metric Selection
Choose metrics that:
* Align with goals
* Provide actionable insights
* Are measurable
* Drive improvement
* Support decisions
### 2. Data Quality
Ensure data accuracy:
* Regular validation
* Clean data
* Consistent tracking
* Complete information
* Timely updates
### 3. Report Design
Create effective reports:
* Clear layout
* Relevant metrics
* Visual clarity
* Actionable insights
* Regular updates
### 4. Analysis Process
Follow structured analysis:
* Define objectives
* Gather data
* Analyze patterns
* Draw conclusions
* Make recommendations
## Integration Options
### Data Sources
Connect with:
* Task database
* Time tracking
* Project management
* External systems
* Custom sources
### Export Options
Export data to:
* Excel
* PDF
* CSV
* API endpoints
* Custom formats
## Security and Privacy
### Data Protection
Secure analytics data:
* Access controls
* Data encryption
* Audit logging
* Privacy compliance
* Data retention
### User Permissions
Control access to:
* Metrics visibility
* Report access
* Export rights
* Analysis tools
* Custom reports
For more information about task settings, see [Task Settings](./settings.mdx).
# Creating Tasks
Source: https://docs.casebender.com/en/tasks/creating-tasks
This guide explains the different methods and options available for creating tasks in the system.
## Methods of Creation
### 1. Manual Creation
Tasks can be created manually through several interfaces:
* Using the "New Task" button in the task list
* From within a case detail view
* Through the quick actions menu
* Via the task templates interface
!\[Create Task Dialog]
*Screenshot showing the task creation dialog with all available fields*
### 2. From Templates
Task templates provide standardized formats for common tasks:
* Select from predefined templates
* Use organization-specific templates
* Customize template fields
* Save new templates for reuse
!\[Task Templates]
*Screenshot showing the template selection interface*
### 3. From Cases
Create tasks directly within cases:
* Add investigation tasks
* Create follow-up actions
* Set up review tasks
* Generate documentation tasks
## Required Fields
When creating a task, these fields are mandatory:
* **Title**: Clear description of the task
* **Priority**: Importance level
* **Due Date**: Completion deadline
* **Status**: Initial task state
* **Type**: Task category
## Optional Fields
Additional fields available during task creation:
* **Description**: Detailed task information
* **Assignee**: Responsible team member
* **Parent Case**: Associated case
* **Dependencies**: Related tasks
* **Attachments**: Relevant files
* **Custom Fields**: Organization-specific data
## Task Creation Settings
Administrators can configure task creation options:
* Default values
* Required fields
* Available templates
* Custom fields
* Automation rules
!\[Task Settings]
*Screenshot showing the administrative settings for task creation*
## Task Types
Common task types include:
1. **Investigation Tasks**
* Evidence collection
* Analysis work
* Incident response
2. **Documentation Tasks**
* Report writing
* Evidence documentation
* Procedure updates
3. **Review Tasks**
* Quality assurance
* Peer review
* Management approval
4. **Operational Tasks**
* System updates
* Configuration changes
* Maintenance work
## Priority Levels
Tasks can be assigned different priority levels:
* **Critical**: Immediate attention required
* **High**: Urgent but not critical
* **Medium**: Normal priority
* **Low**: Can be addressed later
## Best Practices
### 1. Task Naming
* Use clear, action-oriented titles
* Include key information in the title
* Follow naming conventions
### 2. Task Planning
* Set realistic deadlines
* Consider dependencies
* Align with team capacity
### 3. Task Assignment
* Match skills to requirements
* Consider workload balance
* Include necessary context
### 4. Task Organization
* Use appropriate templates
* Add relevant tags
* Link related items
## Automation Options
Tasks can be created automatically through:
* Case triggers
* Scheduled events
* Integration webhooks
* Custom workflows
## Task Dependencies
When creating dependent tasks:
1. Identify prerequisites
2. Set logical order
3. Define relationships
4. Configure notifications
## Next Steps
After creating a task:
1. Add detailed description
2. Attach relevant files
3. Set up notifications
4. Brief assigned members
5. Monitor progress
## Integration Features
Tasks integrate with:
* Case management
* Team calendars
* Email notifications
* External systems
For more information on managing tasks, see [Working with Tasks](./working-with-tasks.mdx).
# Task Management
Source: https://docs.casebender.com/en/tasks/introduction
The Task Management system provides a structured way to create, track, and manage action items within cases and investigations.
## Overview
Tasks are actionable items that need to be completed as part of case investigations or general security operations. Each task represents a specific action, assignment, or milestone that contributes to resolving a case or addressing a security concern.
!\[Task List View]
*Screenshot showing the main task list view with filters, priorities, and assignments*
## Key Features
* **Task Lifecycle Management**: Track tasks from creation to completion
* **Priority Levels**: Assign and manage task priorities
* **Due Date Tracking**: Set and monitor task deadlines
* **Team Assignment**: Delegate tasks to team members
* **Progress Tracking**: Monitor task completion status
* **Task Dependencies**: Create and manage task relationships
* **Attachment Support**: Add relevant files and documentation
* **Integration with Cases**: Link tasks to specific cases
## Task Properties
### Core Properties
* **Task ID**: Unique identifier (auto-generated)
* **Title**: Clear description of the task
* **Description**: Detailed information about the task
* **Status**: Current state (Open, In Progress, Completed, etc.)
* **Priority**: Importance level (Low, Medium, High, Critical)
* **Due Date**: Deadline for task completion
* **Type**: Category of task (Investigation, Analysis, Documentation, etc.)
### Metadata
* **Created By**: User who created the task
* **Created At**: Timestamp of task creation
* **Updated At**: Last modification timestamp
* **Assigned To**: Team member responsible for the task
* **Parent Case**: Associated case (if applicable)
* **Completion**: Progress percentage or completion status
## Task Organization
Tasks can be organized in multiple ways:
* **By Case**: Tasks associated with specific cases
* **By Priority**: Grouped by importance level
* **By Status**: Organized by current state
* **By Assignee**: Grouped by team member
* **By Due Date**: Chronological organization
* **Custom Views**: User-defined organization methods
## Related Components
Tasks are integrated with several other components:
* **Cases**: Parent cases that tasks belong to
* **Comments**: Discussion threads on tasks
* **Attachments**: Related files and documents
* **Notifications**: Alerts about task updates
* **Timeline**: Activity history of tasks
* **Reports**: Task status and progress reports
!\[Task Detail View]
*Screenshot showing the detailed view of a task with all its components*
## Task Workflows
Tasks follow defined workflows:
1. **Creation**: Initial task setup
2. **Assignment**: Task delegation
3. **Progress Updates**: Status changes
4. **Review**: Quality checks
5. **Completion**: Task closure
## Best Practices
1. **Clear Descriptions**: Write specific, actionable task descriptions
2. **Realistic Deadlines**: Set achievable due dates
3. **Priority Management**: Assign appropriate priority levels
4. **Regular Updates**: Keep task status current
5. **Documentation**: Maintain clear task notes and attachments
## Next Sections
* [Creating Tasks](./creating-tasks.mdx)
* [Task Workflows](./workflows.mdx)
* [Working with Tasks](./working-with-tasks.mdx)
* [Task Settings](./settings.mdx)
* [Task Analytics](./analytics.mdx)
# Task Settings
Source: https://docs.casebender.com/en/tasks/settings
This guide covers the configuration options and settings available for customizing the task management system.
## Access Settings
Navigate to Settings > Tasks to configure task-related options:
!\[Task Settings Page]
*Screenshot showing the main task settings interface*
## Status Configuration
### Managing Task Statuses
Configure available task statuses:
1. **Create Status**:
* Label and description
* Color coding
* Stage assignment
* Order in workflow
2. **Edit Status**:
* Update properties
* Modify transitions
* Change automation
* Adjust permissions
3. **Delete Status**:
* Remove unused statuses
* Handle existing tasks
* Update workflows
!\[Status Management]
*Screenshot of the status management interface*
## Templates
### Task Templates
Create and manage templates:
* Standard templates
* Team templates
* Project templates
* Custom templates
### Template Properties
Configure template settings:
* Default fields
* Required fields
* Automation rules
* Team assignments
* Dependencies
!\[Template Configuration]
*Screenshot showing template creation and editing*
## Field Configuration
### Custom Fields
Add organization-specific fields:
* Text fields
* Number fields
* Date fields
* Selection fields
* User fields
* Custom types
### Field Properties
Configure field settings:
* Field type
* Default value
* Validation rules
* Required status
* Visibility rules
!\[Custom Fields]
*Screenshot of custom field configuration*
## Automation Settings
### Workflow Rules
Configure automated actions:
1. **Triggers**:
* Status changes
* Priority updates
* Due date changes
* Assignment changes
* Custom events
2. **Actions**:
* Update fields
* Send notifications
* Create tasks
* Update related items
* External integrations
!\[Workflow Automation]
*Screenshot of workflow automation settings*
## Team Settings
### Access Control
Configure team permissions:
* View permissions
* Edit permissions
* Delete permissions
* Assignment rules
* Template access
### Team Organization
Set up team structure:
* Team hierarchy
* User groups
* Role definitions
* Access levels
* Collaboration rules
!\[Team Configuration]
*Screenshot showing team and permission settings*
## Integration Settings
### External Systems
Configure integrations with:
* Project management tools
* Communication platforms
* Calendar systems
* Document storage
* Custom applications
### API Configuration
Manage API settings:
* Authentication
* Rate limits
* Webhooks
* Custom endpoints
* Data mapping
!\[Integration Settings]
*Screenshot of integration configuration*
## Notification Settings
### Email Notifications
Configure email alerts for:
* Task creation
* Status changes
* Comments
* Due dates
* Assignments
* Mentions
### System Notifications
Set up in-app notifications:
* Priority levels
* Delivery methods
* Frequency rules
* Custom triggers
* Team alerts
!\[Notification Configuration]
*Screenshot showing notification settings*
## View Settings
### List View
Configure list display:
* Column selection
* Default sorting
* Grouping options
* Filter presets
* Custom views
### Board View
Configure Kanban boards:
* Column layout
* Card design
* Swimlanes
* WIP limits
* Visual indicators
### Calendar View
Configure calendar display:
* Time scale
* Default view
* Color coding
* Event display
* Resource view
!\[View Configuration]
*Screenshot showing view customization options*
## Analytics Settings
### Metrics
Configure tracking for:
* Completion rates
* Time tracking
* Team performance
* Quality metrics
* Custom KPIs
### Reports
Set up reporting:
* Standard reports
* Custom reports
* Dashboards
* Export options
* Scheduling
!\[Analytics Settings]
*Screenshot of analytics and reporting configuration*
## Best Practices
### 1. Status Configuration
* Use clear names
* Logical workflow
* Consistent colors
* Clear transitions
* Regular review
### 2. Template Management
* Standardize common tasks
* Regular updates
* Team feedback
* Clear documentation
* Version control
### 3. Field Organization
* Logical grouping
* Clear labels
* Helpful hints
* Validation rules
* Regular cleanup
### 4. Automation Rules
* Start simple
* Test thoroughly
* Document rules
* Monitor performance
* Regular review
### 5. Security
* Role-based access
* Regular audits
* Secure integrations
* Data protection
* Compliance checks
For information about working with tasks, see [Working with Tasks](./working-with-tasks.mdx).
# Task Workflows
Source: https://docs.casebender.com/en/tasks/workflows
This guide explains how tasks progress through different stages and how to manage task workflows effectively.
## Task Status Stages
Tasks move through several standard stages:
1. **Open**: Newly created tasks awaiting action
2. **In Progress**: Tasks currently being worked on
3. **Under Review**: Tasks pending verification
4. **Completed**: Successfully finished tasks
5. **Blocked**: Tasks that cannot proceed
6. **Cancelled**: Terminated or obsolete tasks
!\[Task Status Flow]
*Diagram showing the progression of tasks through different status stages*
## Status Management
### Status Properties
Each status has specific properties:
* **Label**: Display name
* **Description**: Status meaning
* **Color**: Visual indicator
* **Stage**: Workflow phase
* **Automation Rules**: Associated actions
### Status Transitions
Valid status changes include:
* Open → In Progress
* In Progress → Under Review
* Under Review → Completed
* Any Status → Blocked
* Any Status → Cancelled
!\[Status Transitions]
*Diagram showing valid status transitions and conditions*
## Task Priorities
### Priority Levels
Tasks can be prioritized as:
1. **Critical**
* Immediate action required
* High business impact
* Time-sensitive issues
2. **High**
* Urgent but not critical
* Significant impact
* Near-term deadlines
3. **Medium**
* Standard priority
* Moderate impact
* Flexible timeline
4. **Low**
* Non-urgent
* Minimal impact
* Background tasks
### Priority Management
Effective priority handling:
* Regular priority reviews
* Escalation procedures
* Impact assessment
* Resource allocation
## Workflow Automation
### Automated Actions
Configure actions for:
* Status changes
* Priority updates
* Assignment changes
* Deadline modifications
* Notification triggers
### Trigger Events
Automation can be triggered by:
* Time-based events
* Status changes
* User actions
* External events
* Related task updates
!\[Workflow Automation]
*Screenshot showing workflow automation configuration*
## Task Dependencies
### Types of Dependencies
1. **Finish to Start**
* Task B can't start until Task A finishes
* Most common dependency type
2. **Start to Start**
* Tasks must start together
* Parallel activities
3. **Finish to Finish**
* Tasks must finish together
* Coordinated completion
4. **Start to Finish**
* Rare, specialized dependency
* Complex relationships
### Managing Dependencies
Best practices include:
* Clear documentation
* Visual representation
* Impact analysis
* Change management
## Progress Tracking
### Completion Metrics
Monitor task progress through:
* Percentage complete
* Milestone achievement
* Time tracking
* Quality metrics
### Progress Updates
Regular updates should include:
* Status changes
* Work completed
* Blockers identified
* Next steps planned
## Team Collaboration
### Assignment Rules
Task assignment considers:
* Team member skills
* Current workload
* Availability
* Domain expertise
### Handoff Procedures
When transferring tasks:
1. Document current status
2. Brief new assignee
3. Transfer resources
4. Update stakeholders
## Reporting and Analytics
### Workflow Metrics
Track key indicators:
* Cycle time
* Lead time
* Resolution time
* Blockers
* Efficiency
### Performance Analysis
Analyze workflow health:
* Bottleneck identification
* Resource utilization
* Quality metrics
* Team performance
!\[Workflow Analytics]
*Screenshot showing workflow analytics dashboard*
## Best Practices
### 1. Status Management
* Use clear status definitions
* Regular status updates
* Proper documentation
* Timely transitions
### 2. Priority Handling
* Regular priority reviews
* Clear escalation paths
* Resource alignment
* Impact assessment
### 3. Workflow Efficiency
* Minimize bottlenecks
* Automate routine tasks
* Clear communication
* Regular reviews
### 4. Team Coordination
* Clear responsibilities
* Effective handoffs
* Regular updates
* Team visibility
## Configuration
### Setting Up Workflows
1. Define status stages
2. Configure transitions
3. Set up automation
4. Test workflows
5. Train team members
### Customization Options
Adapt workflows for:
* Team preferences
* Project requirements
* Organization needs
* Compliance rules
For more information on working with tasks, see [Working with Tasks](./working-with-tasks.mdx).
# Working with Tasks
Source: https://docs.casebender.com/en/tasks/working-with-tasks
This guide covers the day-to-day operations and features available when working with tasks in the system.
## Task Interface
The task interface provides comprehensive task management:
!\[Task Interface]
*Screenshot showing the main task interface with all components*
### Key Areas
1. **Header**: Task title and quick actions
2. **Details Panel**: Core task properties
3. **Activity Feed**: Recent updates
4. **Related Items**: Linked content
## Task Views
### 1. List View
The main task list provides:
* Task overview
* Quick filters
* Bulk actions
* Sort options
* Custom views
!\[Task List]
*Screenshot showing the task list view with various options*
### 2. Board View
Kanban-style task management:
* Status columns
* Drag-and-drop
* Visual indicators
* Quick updates
* Team visibility
!\[Task Board]
*Screenshot showing the Kanban board view*
### 3. Calendar View
Time-based task visualization:
* Due date tracking
* Schedule management
* Timeline view
* Resource planning
* Milestone tracking
!\[Task Calendar]
*Screenshot showing the calendar view*
## Task Actions
### Basic Operations
Common task actions include:
* Edit task details
* Update status
* Change priority
* Modify due date
* Add comments
* Attach files
### Advanced Operations
Additional task capabilities:
* Create subtasks
* Set dependencies
* Clone tasks
* Export data
* Generate reports
## Task Components
### 1. Comments
Facilitate team discussion:
* Add updates
* Ask questions
* Share information
* Mention team members
* Attach files
### 2. Attachments
Manage task-related files:
* Upload documents
* Add screenshots
* Link resources
* Version control
* Preview files
### 3. Subtasks
Break down complex tasks:
* Create checklist items
* Track progress
* Assign ownership
* Set priorities
* Monitor completion
### 4. Time Tracking
Monitor task effort:
* Log work hours
* Track estimates
* Record actuals
* View timesheets
* Analyze efficiency
## Task Organization
### Filtering
Filter tasks by:
* Status
* Priority
* Assignee
* Due date
* Tags
* Custom fields
### Sorting
Arrange tasks by:
* Priority
* Due date
* Creation date
* Status
* Assignee
* Custom order
### Grouping
Group tasks by:
* Status
* Assignee
* Priority
* Project
* Custom fields
* Timeline
## Task Communication
### Notifications
Receive updates about:
* Status changes
* Comments
* Assignments
* Due dates
* Mentions
* Attachments
### Integration
Connect with:
* Email
* Slack
* Teams
* Calendar
* Mobile apps
## Task Analysis
### Progress Tracking
Monitor task progress:
* Completion percentage
* Time tracking
* Milestone status
* Dependency status
* Quality metrics
### Performance Metrics
Analyze task efficiency:
* Cycle time
* Lead time
* Resolution time
* Work distribution
* Team velocity
## Mobile Access
### Mobile Features
Access tasks on mobile:
* View task details
* Update status
* Add comments
* Upload photos
* Receive notifications
!\[Mobile Interface]
*Screenshot showing the mobile task interface*
## Best Practices
### 1. Task Management
* Keep tasks updated
* Use clear titles
* Set realistic deadlines
* Track progress regularly
* Document decisions
### 2. Team Collaboration
* Communicate clearly
* Update promptly
* Share context
* Follow up regularly
* Maintain visibility
### 3. Time Management
* Prioritize effectively
* Track time accurately
* Manage deadlines
* Balance workload
* Plan realistically
### 4. Documentation
* Write clear descriptions
* Attach relevant files
* Record decisions
* Update status
* Maintain history
## Keyboard Shortcuts
Common task shortcuts:
* `Ctrl/Cmd + N`: New task
* `Ctrl/Cmd + E`: Edit task
* `Ctrl/Cmd + D`: Duplicate task
* `Space`: Quick update
* `Esc`: Cancel/Close
## Tips and Tricks
### Productivity Tips
1. Use templates for recurring tasks
2. Set up custom views
3. Use bulk actions
4. Configure notifications
5. Utilize keyboard shortcuts
### Organization Tips
1. Use consistent naming
2. Apply relevant tags
3. Group related tasks
4. Maintain clean lists
5. Archive completed tasks
For information about task workflows and status management, see [Task Workflows](./workflows.mdx).
# Time Tracking
Source: https://docs.casebender.com/en/time-tracking
Track analyst effort on cases and alerts, review worklogs, and manage approval and billing status.
Time Tracking records the effort analysts spend investigating cases and alerts. Analysts can run a live timer or log completed work manually, while authorized reviewers can approve worklogs and use the resulting totals for operational and cost reporting.
Start, pause, resume, stop, or discard one active timer from anywhere in the application.
Review descriptions, analysts, dates, categories, durations, entry types, billing state, and approval status.
Keep pending and rejected work visible while limiting approved totals and cost reporting to accepted entries.
## Where Time Tracking appears
Time Tracking is available on supported **Case** and **Alert** detail pages.
* The compact timer in the detail sidebar provides quick start, stop, and manual logging actions.
* The **Time** tab contains the active timer, summary metrics, category allocation, filters, and complete worklog history.
* When you navigate away from the item that owns an active timer, a floating timer remains available so the session is not hidden.
* The interface updates when timer or worklog changes arrive from another tab or authorized user.
Your deployment settings, active organization, parent-resource permissions, TLP access, and role determine which Time Tracking controls are visible. Alert Time Tracking can be rolled out independently from Case Time Tracking.
## Track work with the timer
Only one timer can be active for a user at a time. The elapsed time uses the server-backed session and excludes paused time.
Open the item you are working on. In the compact timer, optionally enter a description and choose an active time category.
Select **Start**. The timer changes to **Running** and remains available in the detail sidebar, the full Time tab, or the floating timer.
Select **Pause timer** to stop adding elapsed time without ending the session. Select **Resume timer** when work continues.
Select **Stop**. Review the description, category, and billable setting, then save the entry. The timer session becomes a `Timer` worklog.
### Switch to another item
CaseBender does not silently move a running timer. When you try to start work on another Case or Alert, use **Stop and switch**:
1. Review and save the current timer.
2. CaseBender creates the current worklog.
3. A new timer starts on the selected item.
This keeps time attribution explicit and prevents one investigation from receiving another investigation's elapsed time.
### Discard a timer
Use **Discard** only when the active session should not become a worklog. CaseBender asks for confirmation because the elapsed time is permanently omitted from active time reporting. The discard action is still recorded for audit purposes.
Discarding a timer cannot be undone from the Time Tracking interface. Stop and save the timer when the work should remain part of the investigation record.
## Log time manually
Use **Log time** when the work has already been completed or was performed away from the live timer.
1. Enter hours and minutes. A worklog must contain at least one minute.
2. Select the local calendar date on which the work occurred.
3. Add a concise description of the completed work.
4. Choose the most appropriate active category.
5. Set whether the work is billable when your permissions allow it.
6. Select **Log time**.
The resulting worklog is labeled `Manual`. System-created entries, when enabled by an applicable workflow, are labeled `Automatic`.
Use descriptions that explain the outcome, not only the activity. For example, prefer “Validated the suspicious sign-in and contained the account” over “Investigation.”
## Understand worklog status
Whether a new or edited worklog requires review is configured per user, with the deployment approval policy used as the fallback.
| Status | Meaning | Reporting behavior |
| ------------ | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| **Draft** | The entry is still being prepared by a supported system workflow. | Not included in approved totals. |
| **Pending** | The entry was submitted and requires approval. | Shown in pending totals; not included in approved totals. |
| **Approved** | An authorized reviewer accepted the entry, or the user is configured for automatic approval. | Included in approved, category, billable, and cost totals. |
| **Rejected** | A reviewer returned the entry with a correction reason. | Shown in rejected totals; not included in approved totals. |
Editing an entry sends it through the user's current approval policy again. Any previous approval or rejection metadata is cleared so the revised values can be evaluated consistently.
## Review and filter worklogs
The **Worklog history** presents the description as the primary content and groups the analyst, date, category, entry type, billing state, duration, and status around it.
Use the compact filter toolbar to narrow the history:
* **Date range** uses one start-and-end calendar selection.
* **Category** limits results to one active time category.
* **Analyst** selects entries from one user when your role allows cross-user access.
* **More filters** contains status, billable/non-billable, and entry type.
* **Clear filters** appears only when one or more filters are active and shows the active filter count.
Use **Load more** to continue through older entries without losing the active filters.
### Edit or delete your worklog
Open the worklog action menu to manage an entry:
* **Edit entry** changes the date, duration, description, category, or billable state.
* **Delete entry** removes the entry from active reports.
The standard Time tab exposes edit and delete actions only for the worklog owner with update access to the parent item. Deletion is soft: CaseBender keeps the immutable audit evidence while excluding the entry from active history and summaries.
## Approve or reject time
Super administrators and organization administrators with the required scoped finance and parent-resource permissions can review pending work.
### Approve from the Time tab
A pending row shows a clear **Approve** action. Use the action menu to reject the entry, then provide a meaningful correction reason for the analyst.
### Process the approval queue
Open **Finance → Approvals** to review pending entries across the authorized scope.
* Select one entry to approve or reject it.
* Enter a rejection reason before confirming a rejection.
* Select multiple entries and use bulk approval for a reviewed batch.
Approval triggers cost reconciliation for the accepted entry. Rejection preserves the worklog and reason so the analyst can correct and resubmit it.
## Read summary metrics
The Time tab separates work by approval state:
* **Approved** — accepted duration included in operational totals.
* **Pending approval** — submitted duration waiting for review.
* **Rejected** — returned duration requiring correction.
* **Approved billable** — accepted duration marked billable.
* **Approved time by category** — accepted duration allocated across categories.
Pending and rejected work remain visible but do not inflate approved or billable reporting.
## Alert promotion and Case attribution
When an Alert is promoted or linked to a Case, its time entries keep their Alert origin and also gain the Case attribution.
* The Alert Time tab continues to show the original work and links to the Case Time tab.
* The Case Time tab includes that Alert-origin work and identifies its provenance.
* CaseBender uses one authoritative worklog row, so the same duration is not added twice to Case totals.
* An active Alert timer is attached to the Case if promotion occurs while the timer is running.
This preserves the investigation history while producing one consolidated Case total.
## Permissions
Time Tracking follows the access controls of the parent Case or Alert.
| Action | Typical requirement |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| View the parent item and available time history | Parent `read` permission, organization/TLP access, and any reporting permission required for cross-user totals |
| Start, pause, resume, stop, discard, or manually log time | Parent `update` permission and write access |
| Edit a worklog from the Time tab | Worklog ownership and parent update access |
| Delete a worklog from the Time tab | Worklog ownership and parent update access |
| View cross-user summaries | Authorized management role and scoped finance read access |
| Approve or reject entries | Super administrator or organization administrator, plus scoped finance write and parent update access |
| Override billable or rate information | Scoped financial override permission |
Authorization is enforced by the server. A hidden or disabled control does not replace permission checks, and a sufficient role does not bypass organization, parent-resource, or TLP boundaries.
## Audit and realtime behavior
CaseBender records creation, edits, deletion, approval, rejection, timer start, pause, resume, stop, and discard events. Worklog access and bulk approval operations are also audited where applicable.
Time-entry and timer events are published to connected clients so active views converge without frequent polling. If realtime delivery is interrupted, the application periodically refreshes the authoritative active timer as a safety net.
## Deployment controls
Time Tracking is enabled by default in packaged and hosted deployments. Operators can explicitly disable either surface as an emergency kill switch or for a staged rollout.
| Environment variable | Scope |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `CASE_SIDEBAR_TIMER` | Shows the compact Case sidebar timer. Case Time history remains available when this compact surface is disabled. |
| `ALERT_TIME_TRACKING` | Controls the Alert timer/worklog interface and Alert-targeted writes. Existing records remain readable for audit and rollback verification. |
Unset flags resolve to enabled. Accepted enabled values include `true`, `1`, and `on`; accepted disabled values include `false`, `0`, and `off`. Invalid configured values resolve to disabled. These flags are process-wide, not organization-specific.
For a staged production rollout, explicitly disable both flags before deploying the new image. Enable Case tracking before Alert tracking, and verify timer, approval, cost, realtime, and reconciliation metrics before expanding access.
## Troubleshooting
### The Start or Log time action is missing
Confirm that the applicable rollout flag is not explicitly disabled, you can update the parent Case or Alert, and your active organization and TLP access include that item.
### A timer is already running elsewhere
Only one active timer is allowed per user. Open the floating timer or select **Stop and switch** from the new item.
### Approved totals did not increase
Check the worklog status. Pending and rejected entries are displayed separately and are excluded from approved totals until accepted.
### A promoted Alert appears in both views
This is expected. The Alert view shows origin attribution and the Case view shows the consolidated investigation. Both views reference the same authoritative worklog, so Case totals are not doubled.
### Another user's worklogs are unavailable
Cross-user history and summaries require an authorized management role, scoped finance read access, and access to the parent resource.
## Recommended practices
* Start the timer when focused work begins and pause it during interruptions.
* Stop and save before switching investigations.
* Use consistent categories for comparable reporting.
* Write outcome-oriented descriptions.
* Correct rejected work promptly and review the supplied reason.
* Reserve bulk approval for entries that have already been reviewed.
* Use **Discard** only for sessions that should not become worklogs.
## Related documentation
* [Working with Cases](/en/cases/working-with-cases)
* [Alert Detail View](/en/alerts/detail-view)
* [Access Control](/en/security/access-control)
* [Audit Logging](/en/security/audit-logging)
# Create Alert
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/alert-create
POST /alerts
Create a new alert
# Delete Alert
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/delete
DELETE /alerts/{id}
Soft delete an alert
# Get Alerts
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/get
GET /alerts
Search and list alerts with filters and pagination
# Get Alert by Id
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/get-by-id
Get /alerts/{id}
Retrieve a specific alert by its ID
# Get Alert Checklist
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/get-checklist
GET /alerts/{id}/checklist
Retrieve the policy snapshot and current checklist state for an alert.
# Get Alert Checklist Item
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/get-checklist-item
GET /alert-checklist-items/{id}
Retrieve a checklist item and its current optimistic-concurrency revision.
# List Checklist Item Activity
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/get-checklist-item-activity
GET /api/v1/alert-checklist-items/{id}/activity
Retrieve paginated state and comment activity for an alert checklist item.
Requires the `alerts:read` scope and access to the parent alert.
Use `cursor` and `limit` query parameters to page through the history. The response returns `items` in reverse chronological order and a `nextCursor` when another page is available.
# Merge Alert with Case
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/merge-alert-with-case
POST /alerts/{alertId}/merge/{caseId}
# Override Alert Checklist Closure
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/override-checklist-closure
POST /alerts/{id}/checklist/closure-override
Record a privileged, reasoned override when checklist policy permits it.
Requires the dedicated `alerts:close-override` scope. The effective policy must permit privileged overrides, at least one required item must remain unresolved, and the request must contain a meaningful reason.
This endpoint records the override. Send the subsequent alert status update separately. Reopening the alert or changing a checklist item clears the active override, so a later closure requires a new authorization and reason.
# Get Alert Statistics
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/stats
GET /alerts/stats
Get aggregated statistics about alerts
# Update Alert
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/update
PUT /alerts/{id}
Update an existing alert
# Complete or Reopen Alert Checklist Item
Source: https://docs.casebender.com/en/api-reference/endpoint/alert/update-checklist-item
PATCH /alert-checklist-items/{id}
Mutate a checklist item using its revision as an optimistic-concurrency precondition.
Requires the `alerts:write` scope. Send the latest `expectedRevision`; stale revisions return `409 Conflict` with the current revision.
Use an `Idempotency-Key` header for completion or reopen requests that may be retried. The same item, action, and key return the existing result without duplicating comments or audit events.
The `complete` action can include a comment and an evidence reference. Attachment evidence must belong to this checklist item. Automation evidence must reference a workflow execution for the parent alert.
# Create API Key
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/create
POST /api-keys
Create a new API key
# List API Keys
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/list
GET /api-keys
List all API keys for the current user or organization
# Create Case
Source: https://docs.casebender.com/en/api-reference/endpoint/case/create
POST /cases
Create a new case
# Delete Case
Source: https://docs.casebender.com/en/api-reference/endpoint/case/delete
DELETE /cases/{id}
Delete a case (soft delete)
# Search Cases
Source: https://docs.casebender.com/en/api-reference/endpoint/case/get
GET /cases
Search and list cases with filters and pagination
# Get Case
Source: https://docs.casebender.com/en/api-reference/endpoint/case/get-by-id
GET /cases/{id}
Retrieve a specific case by its ID
# Get Case Statistics
Source: https://docs.casebender.com/en/api-reference/endpoint/case/stats
GET /cases/stats
Get aggregate statistics for cases
# Update Case
Source: https://docs.casebender.com/en/api-reference/endpoint/case/update
PUT /cases/{id}
Update an existing case. Status changes to 'Closed' require all mandatory tasks to be completed unless X-Skip-Mandatory-Validation header is set with admin privileges.
# Add Alert Comment
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/alert-comments-add
POST /alerts/{alertId}/comments
# Get Alert Comments
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/alert-comments-get
GET /alerts/{alertId}/comments
# Add Case Comment
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/case-comments-add
POST /cases/{caseId}/comments
# Get Case Comments
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/case-comments-get
GET /cases/{caseId}/comments
# Delete Comment
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/delete
DELETE /comments/{id}
# Add Task Comment
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/task-comments-add
POST /tasks/{taskId}/comments
# Get Task Comments
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/task-comments-get
GET /tasks/{taskId}/comments
# Update Comment
Source: https://docs.casebender.com/en/api-reference/endpoint/comments/update
PUT /comments/{id}
# Detailed Health Check
Source: https://docs.casebender.com/en/api-reference/endpoint/health/detailed
GET /health/detailed
Get detailed health information including metrics
# Liveness Probe
Source: https://docs.casebender.com/en/api-reference/endpoint/health/liveness
GET /health
Check if the API service is running
# Readiness Probe
Source: https://docs.casebender.com/en/api-reference/endpoint/health/readiness
GET /health/ready
Check if the API service is ready to accept traffic
# Get Case Observables
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/case-observables
GET /cases/{caseId}/observables
Get all observables for a specific case
# Create Observable
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/create
POST /observables
Create a new observable/IOC
# Delete Observable
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/delete
DELETE /observables/{id}
Delete an observable
# Get Observable by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/get-by-id
GET /observables/{id}
Retrieve a specific observable
# List Observables
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/list
GET /observables
List all observables with optional filters
# Get Observable Types
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/types
GET /observable-types
Get list of available observable types
# Update Observable
Source: https://docs.casebender.com/en/api-reference/endpoint/observables/update
PUT /observables/{id}
Update an existing observable
# Create Organization
Source: https://docs.casebender.com/en/api-reference/endpoint/organizations/create
POST /organizations
Create a new organization (admin only)
# Delete Organization
Source: https://docs.casebender.com/en/api-reference/endpoint/organizations/delete
DELETE /organizations/{id}
Soft delete an organization (admin only)
# Get Organization by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/organizations/get-by-id
GET /organizations/{id}
Retrieve a specific organization by its ID
# Get Organization Hierarchy
Source: https://docs.casebender.com/en/api-reference/endpoint/organizations/hierarchy
GET /organizations/hierarchy
Get the organization hierarchy tree
# List Organizations
Source: https://docs.casebender.com/en/api-reference/endpoint/organizations/list
GET /organizations
List all organizations with optional filters
# Update Organization
Source: https://docs.casebender.com/en/api-reference/endpoint/organizations/update
PUT /organizations/{id}
Update an existing organization (admin only)
# Create Playbook
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/create
POST /playbooks
Create a new playbook
# Delete Playbook
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/delete
DELETE /playbooks/{id}
Delete a playbook
# Get Playbook Executions
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/executions
GET /playbooks/{id}/executions
Get execution history for a playbook
# Get Playbook by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/get-by-id
GET /playbooks/{id}
Retrieve a specific playbook by its ID
# List Playbooks
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/list
GET /playbooks
List all playbooks with optional filters
# Trigger Playbook
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/trigger
POST /playbooks/{id}/trigger
Manually trigger a playbook execution
# Update Playbook
Source: https://docs.casebender.com/en/api-reference/endpoint/playbooks/update
PUT /playbooks/{id}
Update an existing playbook
# Get Case Tasks
Source: https://docs.casebender.com/en/api-reference/endpoint/task/case-tasks
GET /cases/{caseId}/tasks
Get all tasks for a specific case
# Create Task
Source: https://docs.casebender.com/en/api-reference/endpoint/task/create
POST /task
# Delete Task
Source: https://docs.casebender.com/en/api-reference/endpoint/task/delete
DELETE /task/{id}
# Get External Ticket
Source: https://docs.casebender.com/en/api-reference/endpoint/task/external-ticket-get
GET /tasks/{id}/external-ticket
Get the linked external ticket (ServiceNow/Jira) for a task (FUNC-038)
# Get Task by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/task/get-by-id
GET /tasks/{id}
Retrieve a specific task
# Create Jira Issue
Source: https://docs.casebender.com/en/api-reference/endpoint/task/jira-create
POST /tasks/{id}/external-ticket/jira
Create a Jira issue from a task with auto-populated data (FUNC-038)
# List Tasks
Source: https://docs.casebender.com/en/api-reference/endpoint/task/list
GET /tasks
List all tasks with optional filters including team assignment (FUNC-045)
# Create ServiceNow Ticket
Source: https://docs.casebender.com/en/api-reference/endpoint/task/servicenow-create
POST /tasks/{id}/external-ticket/servicenow
Create a ServiceNow incident from a task with auto-populated data (FUNC-038)
# Update Task
Source: https://docs.casebender.com/en/api-reference/endpoint/task/update
PUT /tasks/{id}
Update an existing task including team assignments (FUNC-045) and TLP classification (FUNC-044). TLP can only be elevated (increased), not lowered below the parent case's TLP level.
# Add User to Team
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/add-user
POST /teams/{id}/users/{userId}
Add a user to a team
# Create Team
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/create
POST /teams
Create a new team (admin only)
# Delete Team
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/delete
DELETE /teams/{id}
Delete a team (admin only)
# Get Team by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/get-by-id
GET /teams/{id}
Retrieve a specific team by its ID
# List Teams
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/list
GET /teams
List all teams with optional filters
# Remove User from Team
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/remove-user
DELETE /teams/{id}/users/{userId}
Remove a user from a team
# Update Team
Source: https://docs.casebender.com/en/api-reference/endpoint/teams/update
PUT /teams/{id}
Update an existing team (admin only)
# Get User by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/users/get-by-id
GET /users/{id}
Retrieve a specific user
# List Users
Source: https://docs.casebender.com/en/api-reference/endpoint/users/list
GET /users
List all users with optional filters
# Get Current User
Source: https://docs.casebender.com/en/api-reference/endpoint/users/me
GET /users/me
Get the currently authenticated user
# Update User
Source: https://docs.casebender.com/en/api-reference/endpoint/users/update
PUT /users/{id}
Update an existing user (admin only)
# Create Webhook
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/create
POST /webhooks
Create a new webhook subscription
# Delete Webhook
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/delete
DELETE /webhooks/{id}
Delete a webhook subscription
# Get Delivery Logs
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/deliveries
GET /webhooks/{id}/deliveries
Get delivery history for a webhook
# List Event Types
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/event-types
GET /webhooks/event-types
Get all available webhook event types
# Get Webhook by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/get-by-id
GET /webhooks/{id}
Retrieve a specific webhook subscription
# List Webhooks
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/list
GET /webhooks
List all webhook subscriptions
# Test Webhook
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/test
POST /webhooks/{id}/test
Send a test payload to a webhook
# Update Webhook
Source: https://docs.casebender.com/en/api-reference/endpoint/webhooks/update
PUT /webhooks/{id}
Update an existing webhook subscription
# Create Workflow
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/create
POST /workflows
Create a new workflow
# Delete Workflow
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/delete
DELETE /workflows/{id}
Delete a workflow
# Execute Workflow
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/execute
POST /workflows/{id}/execute
Execute a workflow manually with provided context
# Get Workflow Executions
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/executions
GET /workflows/{id}/executions
Get execution history for a workflow
# Get Workflow by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/get-by-id
GET /workflows/{id}
Retrieve a specific workflow
# List Workflows
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/list
GET /workflows
List all workflows with optional filters
# Update Workflow
Source: https://docs.casebender.com/en/api-reference/endpoint/workflows/update
PUT /workflows/{id}
Update an existing workflow
# Introduction
Source: https://docs.casebender.com/en/api-reference/introduction
CaseBender API endpoints
View the OpenAPI specification file
## Authentication
All API endpoints require authentication using API keys. Include your API key in every request using one of the following methods:
### Recommended: Bearer Token
Include your API key as a Bearer token in the `Authorization` header:
```bash theme={null}
Authorization: Bearer cbr_live_your_api_key_here
```
### Alternative: X-Api-Key Header
You can also use the `X-Api-Key` header:
```bash theme={null}
X-Api-Key: cbr_live_your_api_key_here
```
**Important**: Your API key grants access to your CaseBender instance. Keep it secure and never share it publicly.
### Creating API Keys
To create API keys:
1. Log in to your CaseBender instance
2. Navigate to **Account** → **API Keys**
3. Click **Create API Key**
4. Configure the key name, description, tier, and scopes
5. **Save the key immediately** - it is displayed only once and cannot be retrieved later
When you create an API key, you'll receive a single key that looks like:
```
cbr_live_a1b2c3d4e5f6g7h8i9j0...
```
### Using API Keys
Include the API key in all API requests:
#### Using cURL
```bash theme={null}
curl -X GET https://your-instance.casebender.com/api/v1/alerts \
-H "Authorization: Bearer YOUR_API_KEY_HERE" \
-H "Content-Type: application/json"
```
#### Using Python (requests library)
```python theme={null}
import requests
headers = {
"Authorization": "Bearer YOUR_API_KEY_HERE",
"Content-Type": "application/json"
}
response = requests.get(
"https://your-instance.casebender.com/api/v1/alerts",
headers=headers
)
```
#### Using JavaScript/Node.js (fetch)
```javascript theme={null}
const response = await fetch(
"https://your-instance.casebender.com/api/v1/alerts",
{
method: "GET",
headers: {
"Authorization": "Bearer YOUR_API_KEY_HERE",
"Content-Type": "application/json",
},
}
);
```
### API Key Tiers
API keys record an intended service tier. Effective limits are enforced by the
deployment and can be lower than the tier's nominal ceiling. No tier bypasses
tenant, scope, TLP, owner-status, or organization policy.
| Tier | Requests/Minute | Requests/Hour | Burst Allowance |
| ------------ | ------------------ | ------------------ | ------------------ |
| Basic | 60 | 1,000 | 10 |
| Standard | 300 | 10,000 | 50 |
| Professional | 1,000 | 50,000 | 100 |
| Enterprise | 5,000 | 200,000 | 500 |
| Unlimited | Deployment-defined | Deployment-defined | Deployment-defined |
### API Key Scopes
When creating an API key, you can limit its access to specific operations:
* `alerts:read` - Read alerts
* `alerts:write` - Create and update alerts
* `cases:read` - Read cases
* `cases:write` - Create and update cases
* `observables:read` - Read observables
* `observables:write` - Create and update observables
* `users:read` - Read user information
* Administrative scopes are shown only when the key manager already possesses
the corresponding permission
The API rejects attempts to create a key with scopes or TLP clearance broader
than the caller. Each key remains bound to its server-derived owner and
organization.
### Common Authentication Errors
* **401 Unauthorized**:
* Missing `Authorization` header
* Invalid or expired API key
* API key has been revoked or suspended
* API key owner has been disabled, locked, or deleted
* **403 Forbidden**:
* API key lacks required scope for the operation
* Organization, team, parent-object, or TLP access restrictions
* **429 Too Many Requests**:
* Rate limit exceeded for your tier
### Security Best Practices
* **Never share your API key** - treat it like a password
* **Rotate API keys regularly** - revoke old keys and create new ones periodically
* **Use different keys for different applications** - this allows you to revoke access per application
* **Set expiration dates** - configure API keys to expire automatically when possible
* **Use minimum required scopes** - only grant the permissions your application needs
Only `Authorization: Bearer` and `X-Api-Key` are supported. Query-string
credentials and split legacy key/secret headers are not accepted.
# Audit Logging
Source: https://docs.casebender.com/en/security/audit-logging
CaseBender's unified audit trail, integrity verification, SIEM forwarding, legal hold, and e-discovery support.
## Unified Audit Trail
CaseBender maintains a comprehensive, tamper-evident audit trail that records every significant action across the platform. The audit system is designed to satisfy the most stringent compliance requirements (SOC2 CC7.2, ISO 27001 A.8.15, HIPAA 164.312(b), CMMC AU.L2-3.3.1).
### What's Logged
Every audit entry captures:
| Field | Description |
| -------------------- | ------------------------------------------------------------------------ |
| **Timestamp** | Precise UTC timestamp of the action |
| **Actor** | Who performed the action (user, system, integration, or API key) |
| **Action** | What was done (create, read, update, delete, export, authenticate, etc.) |
| **Target** | What entity was affected (case, alert, task, user, configuration, etc.) |
| **Changes** | Before and after values for modifications |
| **Context** | IP address, user agent, session ID, tenant ID |
| **Compliance Flags** | Which compliance frameworks this event satisfies |
### Event Categories
| Category | Examples |
| ------------------- | --------------------------------------------------------------------- |
| **Entity Access** | Case viewed, alert accessed, evidence downloaded |
| **Entity Changes** | Case updated, alert status changed, task assigned |
| **Authentication** | Login, logout, MFA challenge, SSO assertion, lockout |
| **Authorization** | Access granted, access denied, privilege elevated, role changed |
| **System Events** | Service started, configuration changed, backup completed |
| **Data Export** | Audit log exported, case data exported, report generated |
| **Security Events** | Anomaly detected, threat indicator triggered, policy violation |
| **Bulk Operations** | Bulk update, bulk delete, bulk assign (with individual item tracking) |
### Query and Search
The audit trail supports powerful querying:
* **Full-Text Search**: Search across all audit fields
* **Filtered Views**: Filter by date range, actor, action type, entity type, and more
* **Saved Filters**: Save commonly used filter combinations
* **Export**: Export filtered results in PDF, CSV, or structured JSON
* **Scheduled Reports**: Configure recurring audit reports delivered via email
## Audit Integrity
### Tamper-Evident Hash Chains
CaseBender protects audit log integrity using HMAC-SHA-256 hash chains:
* Each audit entry authenticates its protected fields and the previous entry's
hash with the installation-specific `AUDIT_INTEGRITY_SECRET`
* This creates an immutable chain — modifying any entry would break the chain
* Integrity verification can detect tampering at any point in the chain
* Verification can be performed on-demand or on a schedule
Entries created before chained auditing was enabled remain visible as legacy,
unchained records. Verification reports their count separately and requires
every entry created after chain activation to be authenticated.
### Integrity Key Operations
* Production `web`, `api`, and `worker` processes must receive the same
`AUDIT_INTEGRITY_SECRET`.
* Generate the key once per installation and store it in the deployment's
approved secret manager.
* Preserve it with database and environment backups. Restoring the database
without the matching key prevents verification of existing chained entries.
* Do not rotate or regenerate it during routine upgrades, container recreation,
rollback, or disaster recovery. Key rotation requires a separately designed
chain-version transition.
* Never print the value in deployment logs, support tickets, or audit exports.
### Integrity Verification
* **On-Demand Verification**: Administrators can verify audit log integrity at any time
* **Scheduled Verification**: Automated integrity checks run on a configurable schedule
* **Verification Report**: Detailed report showing chain integrity status, any gaps, and anomalies
* **Alert on Tampering**: If integrity verification fails, a security alert is generated immediately
Audit log integrity verification satisfies SEC Rule 17a-4 (WORM storage equivalent), SOC2 CC7.2 (system monitoring), and ISO 27001 A.8.15 (logging).
## SIEM Forwarding
CaseBender forwards audit events to your existing SIEM in real-time for centralized security monitoring.
### Supported Destinations
| Destination | Protocol | Formats |
| ---------------------- | -------------------------- | --------------------- |
| **Splunk** | HTTP Event Collector (HEC) | JSON, CEF |
| **Elastic / ELK** | Elasticsearch API | JSON (ECS-compatible) |
| **IBM QRadar** | Syslog (TCP/TLS) | LEEF |
| **Microsoft Sentinel** | Log Analytics API | JSON |
| **Generic Syslog** | Syslog (TCP/UDP/TLS) | CEF, LEEF, JSON |
| **Custom Webhook** | HTTPS POST | JSON |
### Forwarding Features
* **Multiple Destinations**: Forward to multiple SIEMs simultaneously
* **Event Filtering**: Choose which event categories to forward
* **Buffering**: Events are buffered during SIEM outages and delivered when connectivity is restored
* **Retry Logic**: Failed deliveries are retried with exponential backoff
* **TLS Encryption**: All forwarded events are encrypted in transit
* **Health Monitoring**: Forwarding health is monitored with alerts on delivery failures
## Legal Hold
CaseBender includes a legal hold system for litigation preservation:
### Legal Hold Management
* **Hold Creation**: Create legal holds with scope, custodians, and preservation requirements
* **Scope Definition**: Define what data is preserved (cases, alerts, evidence, communications)
* **Custodian Management**: Track custodians (individuals responsible for preserving data)
* **Evidence Preservation**: Entities under legal hold are exempt from automated retention/deletion
* **Hold Release**: Release holds when litigation concludes, with full audit trail
### Legal Hold Features
| Feature | Description |
| -------------------------- | --------------------------------------------------------- |
| **Automatic Preservation** | Entities matching hold scope are automatically preserved |
| **Retention Override** | Legal holds override data retention policies |
| **Custodian Notification** | Custodians are notified of their preservation obligations |
| **Compliance Tracking** | Track custodian acknowledgment and compliance |
| **Chain of Custody** | Maintain evidence chain of custody documentation |
| **Audit Trail** | All hold actions are logged in the audit trail |
## E-Discovery Support
CaseBender supports the full e-discovery lifecycle:
### E-Discovery Workflow
1. **Request**: Receive and track e-discovery requests with deadlines and scope
2. **Collection**: Collect responsive data from cases, alerts, comments, and audit logs
3. **Review**: Review collected data in dedicated review sets with tagging and annotation
4. **Production**: Produce responsive documents in required formats
5. **Export**: Generate export packages for legal counsel
### Review Capabilities
* **Review Sets**: Organize collected data into review sets for efficient review
* **Tagging**: Tag documents as responsive, privileged, or irrelevant
* **Bulk Review**: Review multiple items simultaneously with consistent tagging
* **Decision Tracking**: Track review decisions with reviewer attribution
* **Export Formats**: PDF, CSV, native format, and structured data packages
## Data Retention for Audit Logs
Audit logs follow configurable retention policies:
| Data Type | Default Retention | Compliance Requirement |
| --------------------- | ----------------- | ---------------------- |
| Authentication events | 3 years | SOC2, ISO 27001, CMMC |
| Authorization events | 3 years | SOC2, ISO 27001, HIPAA |
| Data access events | 3 years | GDPR, HIPAA, PCI DSS |
| Configuration changes | 7 years | SEC Rule 17a-4 |
| Security events | 3 years | SOC2, CMMC, FedRAMP |
| Compliance evidence | 7 years | Multiple frameworks |
Audit logs under legal hold are retained indefinitely regardless of retention policy settings.
## Related Documentation
* [Security Architecture](/en/security/architecture) — How audit logging fits into the security design
* [Compliance Overview](/en/security/compliance-overview) — How audit logs provide compliance evidence
* [Threat Detection](/en/security/behavioral-analytics) — UEBA and SIEM integration
# Threat Detection
Source: https://docs.casebender.com/en/security/behavioral-analytics
User and Entity Behavior Analytics (UEBA), insider threat detection, DDoS protection, and SIEM integration.
## User and Entity Behavior Analytics (UEBA)
CaseBender includes a built-in UEBA engine that establishes behavioral baselines for every user and detects anomalies that may indicate compromised accounts or malicious activity.
### Behavioral Categories Monitored
| Category | What's Tracked | Example Anomaly |
| ------------------- | ----------------------------------------------- | ------------------------------------------ |
| **Authentication** | Login times, locations, devices, MFA usage | Login from new country at unusual hour |
| **Data Access** | Cases viewed, searches performed, exports | Bulk case access outside normal pattern |
| **Case Operations** | Cases created, modified, closed, reassigned | Unusual volume of case closures |
| **Administrative** | Settings changes, user management, role changes | Privilege escalation outside change window |
| **API Usage** | Endpoint access patterns, data volumes | Sudden spike in API calls from a key |
| **Communication** | Comments, notifications, sharing patterns | Mass sharing of restricted cases |
### How Baselines Work
1. **Learning Period**: The system observes user behavior for a configurable baseline window (default: 30 days)
2. **Feature Extraction**: Behavioral features are extracted (time patterns, volume patterns, entity patterns)
3. **Baseline Establishment**: Statistical baselines are created per user and per peer group
4. **Continuous Comparison**: Every action is compared against the user's baseline and their peer group
5. **Anomaly Scoring**: Deviations are scored based on magnitude, frequency, and risk context
### Peer Group Analysis
Users are automatically grouped by role, team, and behavior patterns. Anomalies are evaluated both against individual baselines and peer group norms:
* A SOC analyst accessing 50 cases per day is normal if their peers do the same
* The same access pattern from a user who normally accesses 5 cases per day is anomalous
* Peer group deviations are weighted differently from individual deviations
### Risk Scoring
Each user maintains a dynamic risk score:
| Risk Level | Score Range | Response |
| ------------ | ----------- | ------------------------------------------------------------------------------ |
| **Critical** | 90-100 | Immediate alert to security team, session review, potential account suspension |
| **High** | 70-89 | Alert generated, enhanced monitoring enabled, manager notified |
| **Medium** | 40-69 | Logged for review, included in daily security digest |
| **Low** | 10-39 | Normal monitoring, baseline adjustment |
| **Minimal** | 0-9 | Standard operations |
### ML Adapter
CaseBender's UEBA engine includes an ML adapter interface for organizations that want to integrate advanced machine learning models:
* Feature vector extraction for external ML pipelines
* Anomaly prediction integration
* Model health monitoring
* Supports custom model deployment alongside built-in statistical detection
## Insider Threat Detection
CaseBender provides dedicated insider threat detection capabilities that go beyond UEBA to include investigation workflows, watchlists, and escalation management.
### Threat Indicators
The system monitors for indicators across multiple categories:
* **Data Exfiltration**: Unusual export volumes, bulk downloads, access to cases outside assignment
* **Privilege Abuse**: Unauthorized configuration changes, role manipulation, PAM misuse
* **Policy Violations**: Access outside business hours, from unauthorized locations, bypassing controls
* **Behavioral Changes**: Sudden changes in work patterns, increased access to sensitive data
* **Pre-Departure Risk**: Access pattern changes correlated with HR signals (resignation, termination)
### Investigation Workflow
When indicators are detected:
1. **Alert Generation**: Insider threat alert created with risk score and indicator details
2. **Triage**: Security team reviews the alert and determines if investigation is warranted
3. **Investigation**: Dedicated investigation workspace with timeline, evidence collection, and notes
4. **Watchlist**: Users can be placed on enhanced monitoring watchlists with configurable monitoring levels
5. **Escalation**: Configurable escalation rules route investigations to appropriate teams (security, HR, legal)
6. **Resolution**: Investigations are closed with documented findings and actions taken
### Integration Points
* **HR Systems**: Receive employment status changes (resignation, termination, role change) to adjust risk scoring
* **SIEM**: Forward insider threat events to your SIEM for correlation with other security data
* **Legal Hold**: Automatically initiate legal holds when investigations reach certain severity thresholds
* **Notification**: Alert security managers, HR, and legal teams based on escalation rules
## DDoS Protection
CaseBender includes application-layer DDoS detection and mitigation:
### Detection Methods
* **Traffic Analysis**: Real-time monitoring of request rates, patterns, and sources
* **Request Fingerprinting**: Identifies coordinated attacks from distributed sources
* **Geo-Blocking**: Configurable country-level blocking for regions with no legitimate users
* **Anomaly Detection**: Statistical analysis of traffic patterns against established baselines
### Mitigation
* **Automatic Rate Limiting**: Progressive rate limiting as attack severity increases
* **Challenge Pages**: CAPTCHA challenges for suspicious traffic patterns
* **IP Blocking**: Temporary or permanent blocking of identified attack sources
* **Alerting**: Real-time alerts to operations team with attack details and mitigation status
CaseBender's DDoS protection operates at the application layer. For volumetric network-layer DDoS protection, deploy CaseBender behind a dedicated DDoS mitigation service (e.g., Cloudflare, AWS Shield, or on-premise appliances).
## SIEM Integration
CaseBender forwards security events to your existing SIEM for centralized monitoring and correlation.
### Supported Destinations
| SIEM | Protocol | Format |
| ---------------------- | -------------------------- | --------------- |
| **Splunk** | HTTP Event Collector (HEC) | JSON, CEF |
| **Elastic / ELK** | Elasticsearch API | JSON (ECS) |
| **IBM QRadar** | Syslog | LEEF |
| **Microsoft Sentinel** | Log Analytics API | JSON |
| **Generic Syslog** | Syslog (TCP/UDP/TLS) | CEF, LEEF, JSON |
| **Custom Webhook** | HTTPS POST | JSON |
### Events Forwarded
* Authentication events (login, logout, MFA, lockout)
* Authorization events (access granted, denied, elevated)
* Data access events (entity viewed, exported, modified)
* Security events (anomaly detected, threat indicator, policy violation)
* Administrative events (configuration change, user management)
* System events (service health, error conditions)
### Configuration
SIEM forwarding is configured per organization:
* Multiple destinations can be configured simultaneously
* Event filtering controls which event types are forwarded
* Buffering and retry logic ensures no events are lost during SIEM outages
* TLS encryption for all forwarded events
## Related Documentation
* [Access Control](/en/security/access-control) — RBAC and PAM that generate the events UEBA monitors
* [Audit Logging](/en/security/audit-logging) — The audit trail that feeds UEBA and SIEM
* [Security Architecture](/en/security/architecture) — Zero Trust design that UEBA enforces
# Code Security
Source: https://docs.casebender.com/en/security/code-security
Static analysis, dynamic testing, vulnerability management, penetration testing, and license compliance in CaseBender.
## Overview
CaseBender uses automated static analysis, secret detection, dependency, infrastructure, container, and release supply-chain controls. Authenticated staging DAST is supported when a dedicated target and test identity are configured.
Automated scanning is not an independent penetration test. CaseBender cannot currently claim a completed third-party penetration test; an authenticated assessment and remediation retest are planned.
### Security Scan Workflow
Authorized repository reviewers can inspect the [Security Scan workflow](https://github.com/casebender/webapp/actions/workflows/security-scan.yml), including its job results and retained artifacts.
Because the source repository is private, GitHub workflow badge images return `404 Not Found` when embedded in public documentation without an authorized GitHub session. A workflow result is evidence of configured automation, not certification or proof that the application has no vulnerabilities.
## Static Application Security Testing (SAST)
### ESLint Security Rules
Every pull request is scanned with ESLint security rules that detect:
* Dynamic `eval()` expressions
* Unsafe regular-expression patterns (reported for review)
* Dynamic file, module, and object access patterns
* Insecure Buffer and pseudorandom-number usage
* Potential timing-attack patterns
### Semgrep Deep Analysis
[Semgrep](https://semgrep.dev/) provides deep taint analysis across the TypeScript and Next.js codebase:
* **OWASP Top 10 Rules**: Injection, broken authentication, sensitive data exposure, XSS, insecure deserialization
* **TypeScript-Specific Rules**: Type confusion, unsafe type assertions, prototype pollution
* **Next.js-Specific Rules**: Server-side request forgery, open redirects, insecure API routes
* **Custom Rules**: CaseBender-specific patterns for common security mistakes
### Secret Detection
[Gitleaks](https://gitleaks.io/) scans every commit for accidentally committed secrets:
* API keys and tokens
* Database connection strings
* Private keys and certificates
* Cloud provider credentials
* Generic high-entropy strings
Gitleaks scans both the current commit and the full git history to catch secrets that may have been committed and later removed.
## Dynamic Application Security Testing (DAST)
### OWASP ZAP
[OWASP ZAP](https://www.zaproxy.org/) is configured to perform an authenticated active scan against a dedicated staging application:
* **Schedule**: Weekly (every Sunday at 2 AM UTC)
* **Scan Type**: Full active scan (not just passive observation)
* **Target**: A required non-placeholder `DAST_TARGET_URL`
* **Authentication**: A dedicated test identity supplied through masked repository secrets
* **Preflight**: CaseBender identity and authenticated session are verified before scanning
* **Results**: Preserved as workflow artifacts; SARIF ingestion is used only where GitHub Code Security is licensed
The workflow fails closed when the target or credentials are missing. A successful run must not be interpreted as complete API or business-logic coverage.
### What ZAP Tests
* SQL injection
* Cross-site scripting (XSS)
* Cross-site request forgery (CSRF)
* Server-side request forgery (SSRF)
* Directory traversal
* Remote code execution
* Authentication bypass
* Session management flaws
* Information disclosure
## Vulnerability Management
### Continuous Scanning
Vulnerabilities are detected through multiple channels:
| Scanner | Target | Schedule | Severity Gate |
| ---------------------------- | --------------------------------- | ------------------------------------- | -------------- |
| **Trivy (Filesystem)** | npm dependencies | Every PR | CRITICAL, HIGH |
| **Trivy (Container)** | Container images (all 7 services) | Every PR | CRITICAL, HIGH |
| **Trivy (IaC)** | Dockerfiles, Kubernetes configs | Every PR | CRITICAL, HIGH |
| **pnpm audit** | Production dependencies | Every PR | CRITICAL, HIGH |
| **Dependabot** | All dependencies | Continuous | Automatic PRs |
| **GitHub Dependency Review** | New/changed dependencies | When GitHub Code Security is licensed | CRITICAL, HIGH |
For private repositories without GitHub Code Security, the production `pnpm audit` and Trivy filesystem gates provide the merge-blocking dependency path.
### Vulnerability SLAs
When vulnerabilities are discovered, they must be remediated within defined SLAs:
| Severity | Remediation SLA | Escalation |
| ---------------------------- | --------------- | --------------------------- |
| **Critical** (CVSS 9.0-10.0) | 24 hours | Immediate team notification |
| **High** (CVSS 7.0-8.9) | 7 days | Daily standup review |
| **Medium** (CVSS 4.0-6.9) | 30 days | Weekly review |
| **Low** (CVSS 0.1-3.9) | 90 days | Quarterly review |
### Risk Acceptance
When a vulnerability cannot be immediately remediated (e.g., no patch available), CaseBender follows a formal risk acceptance process:
1. **Documentation**: Vulnerability details, affected components, and business impact
2. **Justification**: Why remediation is not immediately possible
3. **Mitigation**: Compensating controls in place to reduce risk
4. **Review Date**: Mandatory review date (maximum 90 days)
5. **Approval**: Security team approval required
Current Trivy IaC exceptions are tracked in `.trivyignore.yaml` with a scoped path, justification, and mandatory expiry date. This file is not a complete register for every class of accepted product risk.
## Penetration Testing
CaseBender includes a penetration testing management module. This product capability does not demonstrate that CaseBender itself has completed an independent assessment.
No completed third-party penetration-test report or retest letter was found during the July 2026 security review. The planned external scope includes tenant isolation, API authorization, integrations and SSRF, uploads and parsers, secrets, audit integrity, on-premise deployment, and container hardening.
See [Independent Penetration Test Scope](/en/security/penetration-test-scope) for the proposed rules of engagement and required deliverables.
### Engagement Management
* **Engagement Tracking**: Schedule and track penetration testing engagements
* **Scope Definition**: Define testing scope, rules of engagement, and authorized techniques
* **Finding Management**: Track findings with severity, status, and remediation progress
* **Remediation SLAs**: Findings must be remediated within severity-based SLAs
### Remediation SLAs
| Finding Severity | Remediation Deadline |
| ----------------- | -------------------- |
| **Critical** | 15 days |
| **High** | 30 days |
| **Medium** | 60 days |
| **Low** | 90 days |
| **Informational** | Next release cycle |
## License Compliance
### Automated License Scanning
Every dependency's license is checked automatically:
* **Blocked Licenses**: GPL, AGPL, and other strong-copyleft licenses are blocked by default
* **Allowed Licenses**: MIT, Apache 2.0, BSD, ISC, and other permissive licenses
* **Review Required**: LGPL, uncommon, and unknown licenses require legal and distribution review
* **No License**: Dependencies without a declared license are blocked
Exceptions are package-specific and must document their basis. The current policy recognizes lightGallery's commercial dual license and sharp's dynamically linked libvips binaries; it does not suppress those license identifiers for unrelated packages.
### License Scanning Pipeline
Trivy performs license scanning as part of the security scan workflow:
```
Dependency Added → License Detected → Policy Check → Allowed / Blocked / Review Required
```
## Input Validation
CaseBender includes layered input-validation controls intended to reduce injection risk:
### HTML Sanitization
* Rich-text input paths should sanitize user-provided HTML before rendering
* Allowlisted tags and attributes only
* Script tags, event handlers, and data URIs are stripped
### File Upload Validation
* MIME type verification (not just extension checking)
* Blocked extensions: `.exe`, `.bat`, `.cmd`, `.ps1`, `.sh`, `.dll`, `.so`
* Maximum file size enforcement (configurable per upload type)
* Evidence uploads have separate, stricter validation
### URL Validation (SSRF Prevention)
* External URLs are validated before any server-side requests
* Private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x) are blocked
* Internal hostnames and cloud metadata endpoints are blocked
* DNS rebinding protection via pre-resolution validation
### Request Sanitization
* Null byte stripping from all string inputs
* Unicode normalization to prevent homograph attacks
* Zod schemas are used for API input validation
* Prisma parameterized queries are preferred; any raw query requires focused review
## Security Gate
All jobs required by the aggregate Security Gate must pass before code can be merged to the protected main branch:
```
PR Created
├── Gitleaks (secret detection)
├── Trivy (dependency scan)
├── Trivy (container scan × 7 services)
├── Trivy (IaC scan)
├── ESLint Security
├── Semgrep SAST
├── pnpm audit
├── License compliance
├── Dependency review (when licensed)
└── Supply chain verification
│
▼
Security Gate (all must pass)
│
▼
Merge Allowed
```
The security gate is enforced through GitHub branch protection. Direct pushes are rejected when required checks are missing. Authorized repository administrators can change branch-protection policy; those governance changes are separate from a successful security result and should be reviewed through GitHub audit records.
## Related Documentation
* [Security Assurance Program](/en/security/security-assurance) — Control lifecycle, blocking policy, boundaries, and customer responsibilities
* [Supply Chain Security](/en/security/supply-chain) — Container signing, SBOM, and provenance
* [Security Evidence Guide](/en/security/security-evidence) — How to trace and interpret assurance artifacts
* [Security Overview](/en/security/overview) — Live pipeline status
* [Hardening Guide](/en/security/hardening-guide) — Deployment security recommendations
# Additional Compliance Frameworks
Source: https://docs.casebender.com/en/security/compliance-additional
CaseBender's support for CMMC, FedRAMP, HIPAA, PCI DSS, Export Control, and EU AI Act compliance.
## CMMC Level 2
CaseBender supports Cybersecurity Maturity Model Certification (CMMC) Level 2, which requires implementation of 110 practices from NIST SP 800-171.
### Key Capabilities
* **Practice Management**: Track all 110 CMMC Level 2 practices across 14 domains
* **SPRS Scoring**: Calculate and track your Supplier Performance Risk System (SPRS) score over time
* **Assessment Tracking**: Manage self-assessments and third-party assessments (C3PAO)
* **POA\&M Management**: Track Plans of Action and Milestones for practices not yet fully implemented
* **Evidence Collection**: Automated collectors gather evidence mapped to specific practices
### Domain Coverage
| Domain | Practices | Description |
| ----------------------------------------- | --------- | ------------------------------------------------------- |
| **AC** Access Control | 22 | Account management, access enforcement, remote access |
| **AT** Awareness & Training | 3 | Security awareness, role-based training |
| **AU** Audit & Accountability | 9 | Audit logging, audit review, audit protection |
| **CM** Configuration Management | 9 | Baseline configuration, change control |
| **IA** Identification & Authentication | 11 | MFA, device authentication, credential management |
| **IR** Incident Response | 3 | Incident handling, reporting, testing |
| **MA** Maintenance | 6 | System maintenance, maintenance tools |
| **MP** Media Protection | 4 | Media access, storage, transport |
| **PE** Physical Protection | 6 | Physical access, monitoring, visitor control |
| **PS** Personnel Security | 2 | Personnel screening, termination |
| **RA** Risk Assessment | 3 | Risk assessment, vulnerability scanning |
| **CA** Security Assessment | 4 | Assessment, monitoring, system connections |
| **SC** System & Communications Protection | 16 | Boundary protection, encryption, key management |
| **SI** System & Information Integrity | 7 | Flaw remediation, malicious code protection, monitoring |
***
## FedRAMP Moderate
CaseBender supports FedRAMP Moderate authorization, implementing controls from NIST SP 800-53 Rev 5.
### Key Capabilities
* **Control Management**: Track all 325 FedRAMP Moderate controls with implementation status
* **System Security Plan (SSP)**: Manage SSP documentation with version control and approval workflows
* **Continuous Monitoring (ConMon)**: Automated monthly reporting on control effectiveness
* **POA\&M Management**: Track remediation plans with OMB A-130 compliance
* **Authorization Periods**: Manage authorization boundaries, ATOs, and reauthorization schedules
* **Significant Change Management**: Track and assess significant changes that may affect authorization
### Control Families
CaseBender maps its capabilities to all 20 NIST SP 800-53 control families, with particular strength in:
* **AC** (Access Control): RBAC, MFA, session management, PAM
* **AU** (Audit and Accountability): Unified audit trail, integrity protection, SIEM forwarding
* **IA** (Identification and Authentication): Multi-factor, device trust, service authentication
* **IR** (Incident Response): Case management, playbooks, SLA tracking
* **SC** (System and Communications Protection): Encryption, TLS, network segmentation
***
## HIPAA
CaseBender supports HIPAA compliance for organizations that handle Protected Health Information (PHI) as part of security operations.
### Security Rule Safeguards
#### Administrative Safeguards (164.308)
| Safeguard | CaseBender Implementation |
| -------------------------------- | ---------------------------------------------------------------- |
| Security Management Process | Risk assessment, vulnerability management, security monitoring |
| Assigned Security Responsibility | RBAC with defined security roles |
| Workforce Security | SCIM provisioning, access termination, insider threat monitoring |
| Information Access Management | TLP-based access control, data classification, PAM |
| Security Awareness & Training | Compliance training module with HIPAA-specific programs |
| Security Incident Procedures | Case management, incident response workflows, SLA tracking |
| Contingency Plan | Data retention, backup management, disaster recovery |
| Evaluation | Compliance dashboards, control testing, gap analysis |
#### Technical Safeguards (164.312)
| Safeguard | CaseBender Implementation |
| --------------------- | --------------------------------------------------------------------- |
| Access Control | Unique user identification, emergency access, auto-logoff, encryption |
| Audit Controls | Unified audit trail with PHI access logging |
| Integrity | Data integrity verification, tamper-evident audit logs |
| Authentication | MFA, WebAuthn, SSO, account lockout |
| Transmission Security | TLS 1.3, encrypted inter-service communication |
### Breach Notification Rule (164.404-408)
* **Individual Notification**: Generate and track notifications to affected individuals
* **HHS Notification**: Manage notification to the Department of Health and Human Services
* **Media Notification**: For breaches affecting 500+ individuals, manage media notifications
* **Breach Documentation**: Maintain breach records for 6 years as required
### Business Associate Agreements
* Track BAAs with all business associates
* Monitor BAA expiration dates and renewal requirements
* Document BAA terms and data handling obligations
***
## PCI DSS v4.0
CaseBender supports PCI DSS v4.0 for organizations that process payment card data in security investigations.
### Key Capabilities
* **Requirement Tracking**: All 12 PCI DSS requirements with 78 sub-requirements
* **Evidence Collection**: Automated collectors for access controls, encryption, logging, and network security
* **Control Testing**: Scheduled testing with evidence capture and result tracking
* **Incident Management**: PCI-specific incident tracking with notification requirements
* **Assessment Periods**: Manage QSA assessments and self-assessment questionnaires
### Requirement Coverage
| Requirement | Description | CaseBender Mapping |
| ----------- | ----------------------------- | -------------------------------------------------- |
| **1** | Network Security Controls | Network segmentation, firewall configuration |
| **2** | Secure Configurations | Container hardening, configuration management |
| **3** | Protect Stored Data | Encryption at rest, key management, data retention |
| **4** | Protect Data in Transit | TLS 1.3, encrypted communications |
| **5** | Malicious Software Protection | Container scanning, dependency scanning |
| **6** | Secure Development | SAST, DAST, code review, vulnerability management |
| **7** | Restrict Access | RBAC, least privilege, PAM |
| **8** | Identify Users | MFA, unique IDs, authentication management |
| **9** | Physical Access | On-premise deployment documentation |
| **10** | Log and Monitor | Unified audit trail, SIEM forwarding, integrity |
| **11** | Test Security | Penetration testing, vulnerability scanning |
| **12** | Organizational Policies | Policy management, training, incident response |
***
## Export Control
CaseBender includes export control compliance for organizations handling controlled technology data.
### Key Capabilities
* **ECCN/ITAR Classification**: Classify security data and tools under Export Administration Regulations (EAR) and International Traffic in Arms Regulations (ITAR)
* **Denied Party Screening**: Screen entities against government restricted and denied party lists before data sharing
* **Country Controls**: Enforce embargoed and restricted country rules on data access and sharing
* **License Management**: Track export licenses with expiration dates and usage limits
* **Auto-Classification Engine**: Suggest classifications based on data content and context
### Screening Lists
CaseBender screens against:
* Consolidated Screening List (CSL)
* Entity List (BIS)
* Specially Designated Nationals (OFAC SDN)
* Denied Persons List (BIS)
* Debarred List (DDTC)
***
## EU AI Act
CaseBender supports EU AI Act compliance for organizations using AI capabilities within the platform.
### Key Capabilities
* **AI System Registration**: Register and catalog AI systems used within CaseBender (AI insights, auto-enrichment, correlation engine)
* **Risk Assessment**: Evaluate AI systems against EU AI Act risk categories (minimal, limited, high, unacceptable)
* **Incident Reporting**: Report and track AI-related incidents with root cause analysis
* **Conformity Assessment**: Manage conformity assessments for high-risk AI systems
* **Human Oversight**: Document human oversight mechanisms for AI-assisted decisions
* **Transparency**: Maintain transparency records showing how AI systems make recommendations
***
## Related Documentation
* [Compliance Overview](/en/security/compliance-overview) — Framework matrix and unified compliance
* [SOC2 Type II](/en/security/compliance-soc2) — SOC2 deep dive
* [ISO 27001:2022](/en/security/compliance-iso27001) — ISO 27001 deep dive
* [GDPR & Privacy](/en/security/compliance-gdpr) — GDPR deep dive
# GDPR & Privacy
Source: https://docs.casebender.com/en/security/compliance-gdpr
CaseBender's GDPR compliance features including data subject rights, consent management, breach notification, and cross-border transfer controls.
## Overview
CaseBender provides comprehensive GDPR compliance capabilities for organizations that process personal data as part of security operations. As an on-premise platform, CaseBender gives you full control over data processing — your data never leaves your infrastructure.
## Data Subject Rights
### Right of Access (Article 15)
CaseBender supports Data Subject Access Requests (DSARs):
* **Request Management**: Track DSARs from receipt through fulfillment with SLA monitoring
* **Data Discovery**: Automatically discover all data associated with a data subject across cases, alerts, comments, audit logs, and observables
* **Data Export**: Generate structured data packages for data subject delivery
* **Deadline Tracking**: 30-day response deadline with extension management
* **Acknowledgment**: Automated acknowledgment to data subjects upon request receipt
### Right to Erasure (Article 17)
CaseBender implements the right to be forgotten with safeguards:
* **Erasure Execution Engine**: Systematically erases personal data across all platform entities
* **PII Registry**: Comprehensive mapping of where personal data is stored in every database model
* **Anonymization**: Where full deletion would compromise audit integrity, data is anonymized using consistent markers
* **Legal Hold Check**: Erasure requests are automatically checked against active legal holds
* **Verification Report**: Post-erasure verification confirms all personal data has been removed or anonymized
* **Audit Trail**: The erasure action itself is logged (without the erased data) for compliance evidence
### Right to Rectification (Article 16)
* Users can update their personal information through their profile
* Administrators can correct data on behalf of data subjects
* All changes are tracked in the audit trail
### Right to Data Portability (Article 20)
* Data export in structured, machine-readable formats (JSON, CSV)
* Includes all data the subject provided to the platform
* Export packages are encrypted for secure delivery
## Consent Management
### Consent Lifecycle
CaseBender tracks consent throughout its lifecycle:
1. **Collection**: Record consent with purpose, legal basis, and timestamp
2. **Storage**: Consent records are stored with cryptographic integrity
3. **Verification**: Check consent status before processing operations
4. **Withdrawal**: Data subjects can withdraw consent at any time
5. **Impact Assessment**: Withdrawal triggers an impact analysis showing what processing will stop
### Processing Activities Register (Article 30)
Maintain a register of processing activities:
* **Activity Catalog**: Document each processing activity with purpose, legal basis, and data categories
* **Data Flow Mapping**: Track where personal data flows within the platform
* **Retention Periods**: Document retention periods per processing activity
* **Third-Party Sharing**: Record any data sharing with third parties (integrations)
## Breach Notification
### Article 33 — Notification to Supervisory Authority
CaseBender supports the 72-hour breach notification requirement:
* **Breach Detection**: Security monitoring and UEBA detect potential breaches
* **Breach Recording**: Document breach details, affected data, and impact assessment
* **Authority Notification**: Generate notification documents for supervisory authorities
* **Timeline Tracking**: Track the 72-hour deadline with escalation alerts
* **Follow-Up**: Manage supplementary notifications as more information becomes available
### Article 34 — Notification to Data Subjects
When a breach is likely to result in high risk to individuals:
* **Subject Identification**: Identify affected data subjects from breach scope
* **Notification Generation**: Generate clear, plain-language notifications
* **Delivery Tracking**: Track notification delivery and acknowledgment
* **Remediation Guidance**: Include recommended protective measures for affected individuals
## Privacy Impact Assessment
### Automated PIA (Article 35)
CaseBender automates Data Protection Impact Assessments:
* **Personal Data Detection**: Automatically scan entities for personal data patterns
* **Risk Assessment**: Evaluate processing risks based on data types, volume, and sensitivity
* **Mitigation Recommendations**: Suggest privacy-enhancing measures based on identified risks
* **Review Workflow**: PIAs are reviewed and approved by the Data Protection Officer
* **Continuous Monitoring**: PIAs are re-evaluated when processing activities change
## Cross-Border Transfer Controls
### Transfer Safeguards (Articles 44-49)
CaseBender enforces data residency and cross-border transfer rules:
* **Data Residency Policies**: Define where data can be stored and processed by jurisdiction
* **Transfer Rules**: Configure rules for when data can cross borders (adequacy decisions, SCCs, BCRs)
* **Transfer Evaluation**: Automatically evaluate proposed transfers against configured rules
* **Violation Detection**: Detect and alert on unauthorized cross-border data flows
* **Transfer Heatmap**: Visualize data flows across jurisdictions
### Supported Transfer Mechanisms
| Mechanism | Description |
| -------------------------------- | ------------------------------------------------ |
| **Adequacy Decision** | Transfer to countries with EU adequacy decisions |
| **Standard Contractual Clauses** | Transfer under approved SCCs |
| **Binding Corporate Rules** | Intra-group transfers under BCRs |
| **Explicit Consent** | Transfer with explicit data subject consent |
| **Legal Obligation** | Transfer required by law |
## Privacy-Aware Logging
CaseBender implements privacy by design in its logging:
* **PII Redaction**: Personal data is automatically redacted from application logs
* **Configurable Redaction Paths**: Define which fields are redacted in log output
* **Audit vs. Application Logs**: Audit logs retain necessary detail for compliance; application logs are privacy-safe
* **Redaction Strategies**: Support for masking, hashing, and full removal
## Related Documentation
* [Data Protection](/en/security/data-protection) — Encryption and data retention
* [Compliance Overview](/en/security/compliance-overview) — All supported frameworks
* [Audit Logging](/en/security/audit-logging) — Audit trail and integrity
# ISO 27001:2022
Source: https://docs.casebender.com/en/security/compliance-iso27001
CaseBender's ISO 27001:2022 compliance support including ISMS controls, risk management, internal audit, and Statement of Applicability.
## Overview
CaseBender provides comprehensive ISO 27001:2022 Information Security Management System (ISMS) support. The platform maps its security controls to the ISO 27001 Annex A control set and provides tools for risk management, internal audit, and continuous improvement.
## Annex A Control Coverage
### Organizational Controls (A.5)
| Control | Description | CaseBender Implementation |
| ---------- | ------------------------------------------ | ------------------------------------------------------------ |
| **A.5.1** | Policies for information security | Policy management, version control, acknowledgment tracking |
| **A.5.2** | Information security roles | RBAC with defined security responsibilities per role |
| **A.5.3** | Segregation of duties | Role separation, PAM for privileged operations |
| **A.5.7** | Threat intelligence | MITRE ATT\&CK integration, MISP threat feeds, IOC enrichment |
| **A.5.23** | Information security for cloud services | On-premise deployment, cloud hardening guides |
| **A.5.24** | Incident management planning | Case templates, playbook automation, SLA management |
| **A.5.25** | Assessment of information security events | Alert triage workflows, severity scoring, correlation engine |
| **A.5.26** | Response to information security incidents | Case management workflows, task assignment, escalation |
| **A.5.28** | Collection of evidence | Evidence management, chain of custody, legal hold |
### People Controls (A.6)
| Control | Description | CaseBender Implementation |
| --------- | ---------------------------------- | ----------------------------------------------------------------- |
| **A.6.1** | Screening | Integration with HR systems for background check tracking |
| **A.6.3** | Information security awareness | Compliance training module, campaign management |
| **A.6.5** | Responsibilities after termination | SCIM deprovisioning, access revocation, insider threat monitoring |
### Technological Controls (A.8)
| Control | Description | CaseBender Implementation |
| ---------- | ------------------------------ | -------------------------------------------------------------- |
| **A.8.1** | User endpoint devices | Device trust assessment, security posture evaluation |
| **A.8.2** | Privileged access rights | PAM with just-in-time elevation, session recording |
| **A.8.3** | Information access restriction | TLP-based access control, data classification enforcement |
| **A.8.5** | Secure authentication | MFA (TOTP + WebAuthn), SSO (SAML 2.0), account lockout |
| **A.8.9** | Configuration management | Immutable container images, infrastructure as code |
| **A.8.10** | Information deletion | Data retention policies, secure erasure, legal hold exemptions |
| **A.8.11** | Data masking | PII redaction in logs, privacy-aware logging |
| **A.8.12** | Data leakage prevention | Data classification, export controls, UEBA monitoring |
| **A.8.15** | Logging | Unified audit trail, tamper-evident integrity, SIEM forwarding |
| **A.8.16** | Monitoring activities | UEBA, security monitoring, anomaly detection |
| **A.8.24** | Use of cryptography | AES-256 encryption, TLS 1.3, key rotation, secrets management |
## Risk Management
CaseBender includes a dedicated ISO 27001 risk management module:
### Risk Register
* **Risk Identification**: Catalog information security risks with threat and vulnerability mapping
* **Risk Assessment**: Likelihood and impact scoring using configurable risk matrices
* **Risk Treatment**: Define treatment plans with milestones, owners, and deadlines
* **Risk Acceptance**: Formal risk acceptance workflow with management approval and documentation
* **Risk Monitoring**: Track risk levels over time with trend analysis
### Risk Matrix
Risks are evaluated on a 5x5 matrix:
| | Negligible | Minor | Moderate | Major | Catastrophic |
| ------------------ | ---------- | ------ | -------- | -------- | ------------ |
| **Almost Certain** | Medium | High | High | Critical | Critical |
| **Likely** | Low | Medium | High | High | Critical |
| **Possible** | Low | Medium | Medium | High | High |
| **Unlikely** | Low | Low | Medium | Medium | High |
| **Rare** | Low | Low | Low | Medium | Medium |
### Treatment Plans
Each risk treatment plan includes:
* Treatment strategy (mitigate, transfer, accept, avoid)
* Specific actions with owners and deadlines
* Milestones for tracking progress
* Residual risk assessment after treatment
* Review schedule for ongoing monitoring
## Statement of Applicability (SoA)
The SoA documents which Annex A controls are applicable to your deployment:
* **Applicable Controls**: Controls that are relevant and implemented
* **Not Applicable Controls**: Controls excluded with documented justification
* **Implementation Status**: Current implementation level per control
* **Evidence Links**: Direct links to evidence artifacts for each control
* **Approval Workflow**: SoA changes require management approval
## Internal Audit
### Audit Cycle Management
* **Audit Planning**: Define audit scope, schedule, and team assignments
* **Audit Execution**: Guided audit procedures with evidence collection
* **Finding Management**: Track findings by severity (major nonconformity, minor nonconformity, observation, opportunity for improvement)
* **Corrective Actions**: Assign and track corrective actions with deadlines
* **Verification**: Verify corrective action effectiveness before closure
* **Management Review**: Aggregate audit results for management review meetings
### Evidence Collection
Automated collectors gather ISO 27001-specific evidence:
* Access control configurations and reviews
* Security event logs and incident records
* Change management records
* Training and awareness records
* Risk assessment documentation
* Business continuity test results
## Reporting
* **Compliance Dashboard**: Real-time view of ISO 27001 control implementation status
* **Gap Analysis Report**: Identify unimplemented or partially implemented controls
* **Risk Report**: Current risk landscape with treatment status
* **Audit Report**: Internal audit findings and corrective action status
* **Management Review Package**: Aggregated data for management review meetings
## Related Documentation
* [Compliance Overview](/en/security/compliance-overview) — All supported frameworks
* [Data Protection](/en/security/data-protection) — Encryption and data handling controls
* [Threat Detection](/en/security/behavioral-analytics) — Monitoring and detection capabilities
# Compliance Overview
Source: https://docs.casebender.com/en/security/compliance-overview
CaseBender supports 10+ compliance frameworks with built-in evidence collection, control testing, and audit management.
## Compliance Framework Support
CaseBender includes native support for major compliance frameworks. Each framework implementation includes control mapping, automated evidence collection, gap analysis, and reporting — built directly into the platform, not bolted on.
### Framework Matrix
| Framework | Standard | Implementation | Evidence Collection | Reporting |
| -------------------- | ------------------ | ----------------------------------------------------------------------- | ----------------------------------------- | -------------------------------------------- |
| **SOC2 Type II** | AICPA TSC 2017 | Trust Service Criteria mapping, control testing, attestation management | Automated collectors, 3-year retention | Audit period reports, gap analysis |
| **ISO 27001:2022** | ISO/IEC 27001:2022 | Full Annex A controls, Statement of Applicability, risk register | Automated collectors, evidence review | Internal audit reports, management review |
| **GDPR** | EU 2016/679 | Articles 5-88 coverage, DSAR management, consent lifecycle | PII registry, processing activity records | Breach notification, DPIA reports |
| **CMMC Level 2** | NIST SP 800-171 | 110 practices across 14 domains, SPRS scoring | Automated collectors, POA\&M tracking | Assessment reports, SPRS score history |
| **FedRAMP Moderate** | NIST SP 800-53 | 325 controls, continuous monitoring, SSP management | Automated collectors, ConMon reports | Authorization packages, SAR reports |
| **HIPAA** | 45 CFR 160-164 | Security Rule safeguards, breach notification, BAA management | PHI access logging, training records | Disclosure reports, risk assessments |
| **PCI DSS v4.0** | PCI SSC | 12 requirements, 78 sub-requirements | Automated collectors, control testing | Assessment reports, gap analysis |
| **Export Control** | EAR / ITAR | ECCN classification, denied party screening, country controls | Screening logs, license tracking | Transfer reports, compliance dashboards |
| **EU AI Act** | EU 2024/1689 | AI system registration, risk assessment, conformity | Incident reports, oversight records | Risk assessments, transparency reports |
| **Legal Hold** | FRCP / eDiscovery | Litigation preservation, custodian management | Evidence chain of custody | Hold status reports, compliance verification |
### How Compliance Works in CaseBender
Each framework's controls are mapped to CaseBender features and configurations. You can see exactly which platform capabilities satisfy which compliance requirements.
Automated collectors gather evidence from the running platform — audit logs, configuration snapshots, access records — without manual effort.
Identify which controls are fully implemented, partially implemented, or not yet addressed. Prioritize remediation based on risk.
Track audit periods, schedule evidence collection, manage findings, and generate reports for auditors.
## Unified Compliance Dashboard
CaseBender provides a unified view across all enabled compliance frameworks:
### Cross-Framework Visibility
* **Compliance Score**: Aggregate compliance percentage across all frameworks
* **Control Overlap**: Many controls satisfy multiple frameworks simultaneously (e.g., audit logging satisfies SOC2 CC7.2, ISO 27001 A.8.15, CMMC AU.L2-3.3.1, and HIPAA 164.312(b))
* **Gap Prioritization**: Gaps are ranked by how many frameworks they affect
* **Deadline Tracking**: Upcoming audit deadlines, evidence collection schedules, and remediation due dates
* **Activity Feed**: Recent compliance activities across all frameworks
### Regulatory Reporting
* **Automated Report Generation**: Generate framework-specific reports with collected evidence
* **Scheduled Reports**: Configure recurring report generation for continuous compliance
* **Export Formats**: PDF, CSV, and structured data exports for auditor consumption
* **Evidence Packages**: Bundle evidence artifacts with control mappings for audit submissions
## Control Testing
CaseBender includes a unified control testing module that works across all frameworks:
### Testing Capabilities
* **Automated Tests**: Configurable test procedures that run on schedule
* **Manual Tests**: Guided test procedures with evidence capture
* **Cross-Framework Mapping**: A single test can satisfy controls across multiple frameworks
* **Test Scheduling**: Calendar-based scheduling with reminders and escalation
* **Result Tracking**: Pass/fail/partial results with evidence attachment
### Testing Workflow
1. **Schedule**: Tests are scheduled based on framework requirements (quarterly, annually, etc.)
2. **Execute**: Automated tests run automatically; manual tests notify the assigned tester
3. **Evidence**: Test results and supporting evidence are captured automatically
4. **Review**: Results are reviewed and approved by the compliance team
5. **Report**: Test results feed into framework-specific compliance reports
## Compliance Training
Track and manage compliance training requirements:
* **Training Programs**: Define training requirements per framework and role
* **Assignment Management**: Automatically assign training based on user role and team
* **Completion Tracking**: Track completion rates, scores, and certification status
* **Compliance Matrix**: View training compliance across users, teams, and frameworks
* **Campaign Management**: Launch targeted training campaigns for new requirements
## Detailed Framework Documentation
Trust Service Criteria, evidence collection, attestation management
ISMS controls, risk management, internal audit, Statement of Applicability
Data subject rights, consent management, breach notification, cross-border transfers
CMMC, FedRAMP, HIPAA, PCI DSS, Export Control, EU AI Act
## Related Documentation
* [Audit Logging](/en/security/audit-logging) — The audit trail that provides compliance evidence
* [Data Protection](/en/security/data-protection) — Encryption and retention policies
* [Security Overview](/en/security/overview) — Platform security posture
# SOC2 Type II
Source: https://docs.casebender.com/en/security/compliance-soc2
How CaseBender helps you achieve and maintain SOC2 Type II compliance with automated evidence collection and control management.
## Overview
CaseBender provides comprehensive SOC2 Type II support, mapping platform capabilities to Trust Service Criteria and automating evidence collection for audit readiness.
SOC2 Type II evaluates the operating effectiveness of controls over a period of time (typically 6-12 months), making continuous evidence collection essential.
## Trust Service Criteria Coverage
### Security (Common Criteria)
| Control | Description | CaseBender Implementation |
| --------------- | --------------------------- | --------------------------------------------------------- |
| **CC1.1-CC1.5** | Control Environment | Organization management, team structure, role definitions |
| **CC2.1-CC2.3** | Communication & Information | Notification service, audit trail, dashboard reporting |
| **CC3.1-CC3.4** | Risk Assessment | Vulnerability management, risk scoring, threat detection |
| **CC4.1-CC4.2** | Monitoring Activities | UEBA, security monitoring, compliance dashboards |
| **CC5.1-CC5.3** | Control Activities | RBAC, MFA, encryption, input validation |
| **CC6.1-CC6.8** | Logical & Physical Access | Authentication, authorization, PAM, API security |
| **CC7.1-CC7.5** | System Operations | Audit logging, incident response, change management |
| **CC8.1** | Change Management | Version control, deployment pipelines, approval workflows |
| **CC9.1-CC9.2** | Risk Mitigation | SLA management, business continuity, disaster recovery |
### Availability
| Control | Description | CaseBender Implementation |
| -------- | ------------------- | -------------------------------------------------------- |
| **A1.1** | Capacity Management | Resource monitoring, auto-scaling support, health checks |
| **A1.2** | Recovery Procedures | Backup management, disaster recovery, data retention |
| **A1.3** | Recovery Testing | Backup verification, failover testing documentation |
### Confidentiality
| Control | Description | CaseBender Implementation |
| -------- | ----------------------------- | ---------------------------------------------------- |
| **C1.1** | Confidential Information | Data classification, TLP system, access controls |
| **C1.2** | Disposal of Confidential Info | Data retention policies, secure deletion, legal hold |
## Evidence Collection
### Automated Collectors
CaseBender includes automated evidence collectors that gather compliance artifacts without manual effort:
* **Access Control Evidence**: User lists, role assignments, permission matrices, MFA enrollment status
* **Audit Log Evidence**: Authentication events, authorization decisions, data access logs, configuration changes
* **Change Management Evidence**: Deployment history, code review records, approval workflows
* **Encryption Evidence**: Encryption configuration, key rotation history, TLS certificate status
* **Monitoring Evidence**: Alert history, incident response records, UEBA anomaly reports
### Collection Schedule
| Evidence Type | Frequency | Retention |
| ------------------------ | --------- | --------- |
| Access reviews | Quarterly | 3 years |
| Audit log samples | Monthly | 3 years |
| Configuration snapshots | Monthly | 3 years |
| Vulnerability scans | Weekly | 3 years |
| Penetration test results | Annually | 3 years |
| Training records | Quarterly | 3 years |
### Evidence Review Workflow
1. **Collection**: Automated collectors gather evidence on schedule
2. **Review**: Compliance team reviews collected evidence for completeness
3. **Approval**: Evidence is approved and tagged with the relevant control
4. **Storage**: Approved evidence is stored with tamper-evident integrity protection
5. **Retrieval**: Evidence is readily available for auditor review
## Audit Period Management
### Audit Periods
* Define audit periods with start and end dates
* Track evidence collection progress per period
* Monitor control effectiveness across the audit window
* Generate period-specific compliance reports
### Gap Analysis
CaseBender identifies gaps in your SOC2 compliance:
* Controls without sufficient evidence
* Controls with outdated evidence
* Controls that have not been tested within the required timeframe
* New controls introduced by TSC updates that need implementation
### Attestation Management
* Track attestation status per control
* Record control owner attestations
* Manage exception and remediation workflows
* Generate attestation reports for auditors
## Reporting
### Audit Reports
Generate comprehensive reports for your auditors:
* **Control Matrix**: Complete mapping of TSC controls to CaseBender implementations
* **Evidence Package**: Bundled evidence artifacts organized by control
* **Gap Report**: Outstanding gaps with remediation plans and timelines
* **Testing Results**: Control test results with pass/fail status and evidence
### Continuous Monitoring
Between formal audits, CaseBender provides continuous compliance monitoring:
* Real-time compliance score tracking
* Alert on control degradation
* Automated evidence collection ensures no gaps accumulate
* Dashboard showing audit readiness at any point in time
## Related Documentation
* [Compliance Overview](/en/security/compliance-overview) — All supported frameworks
* [Audit Logging](/en/security/audit-logging) — The audit trail powering SOC2 evidence
* [Access Control](/en/security/access-control) — RBAC and PAM controls
# Hardening Guide
Source: https://docs.casebender.com/en/security/hardening-guide
Recommendations for hardening your CaseBender deployment including TLS, database, Redis, container, and monitoring configuration.
## Overview
CaseBender ships with secure defaults, but your deployment environment requires additional hardening. This guide provides recommendations for securing the infrastructure surrounding CaseBender.
This guide covers infrastructure hardening. CaseBender's application-level security (encryption, RBAC, audit logging) is configured within the application itself. See the relevant security documentation pages for application configuration.
## Required production baseline
Before exposing an installation to users:
```bash theme={null}
./casebender preflight
```
The production baseline requires unique installation secrets, authenticated
Redis and OpenSearch, trusted TLS files, pinned image versions, and Nginx as the
only service publishing host ports. Complete
[first-run activation](/en/deployment/first-run-setup), enroll the administrator
in MFA, and store `.env` in an approved secret-management system.
## TLS Configuration
### Reverse Proxy
CaseBender should be deployed behind a reverse proxy (Nginx, Caddy, Traefik, or cloud load balancer) that terminates TLS:
**Recommended TLS Settings:**
| Setting | Value |
| ------------------- | -------------------------------------------------- |
| Minimum TLS Version | TLS 1.2 (TLS 1.3 preferred) |
| Cipher Suites | AEAD ciphers only (AES-256-GCM, ChaCha20-Poly1305) |
| HSTS | Enabled with `max-age=31536000; includeSubDomains` |
| OCSP Stapling | Enabled |
| Certificate Type | RSA 2048+ or ECDSA P-256+ |
**Nginx Example:**
```nginx theme={null}
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
```
### Certificate Management
* Use certificates from a trusted Certificate Authority (Let's Encrypt, DigiCert, etc.)
* Automate certificate renewal (certbot, cert-manager)
* Monitor certificate expiration with alerting (minimum 30 days before expiry)
* Use separate certificates for internal services if implementing mutual TLS
## Database Security
### PostgreSQL Hardening
| Setting | Recommendation |
| ------------------- | ------------------------------------------------------------------------------- |
| **Authentication** | `scram-sha-256` (not `md5` or `trust`) |
| **SSL** | Required for all connections (`ssl = on`, `ssl_min_protocol_version = TLSv1.2`) |
| **Network** | Listen only on private network interfaces |
| **Firewall** | Allow connections only from CaseBender application services |
| **Superuser** | Disable remote superuser access |
| **Logging** | Enable `log_connections`, `log_disconnections`, `log_statement = 'ddl'` |
| **Password Policy** | Minimum 16 characters, rotated quarterly |
**pg\_hba.conf Example:**
```
# Reject all by default
host all all 0.0.0.0/0 reject
# Allow CaseBender services from private network only
hostssl casebender casebender_app 10.0.1.0/24 scram-sha-256
```
### Backup Security
* Encrypt backups at rest (AES-256)
* Store backups in a separate location from the primary database
* Test backup restoration quarterly
* Retain backups according to your compliance requirements (minimum 30 days)
* Monitor backup job success/failure with alerting
## Redis Security
### Redis Hardening
| Setting | Recommendation |
| ---------------------- | ------------------------------------------------------------- |
| **Authentication** | `requirepass` with a strong password (32+ characters) |
| **TLS** | Enable TLS for all connections (`tls-port` instead of `port`) |
| **Network** | Bind to private network interface only (`bind 10.0.1.x`) |
| **Dangerous Commands** | Rename or disable `FLUSHALL`, `FLUSHDB`, `CONFIG`, `DEBUG` |
| **Max Memory** | Set `maxmemory` with `maxmemory-policy allkeys-lru` |
| **Persistence** | Enable AOF persistence for durability |
**redis.conf Example:**
```
bind 10.0.1.5
port 0
tls-port 6379
tls-cert-file /etc/redis/tls/redis.crt
tls-key-file /etc/redis/tls/redis.key
tls-ca-cert-file /etc/redis/tls/ca.crt
requirepass YOUR_STRONG_PASSWORD_HERE
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG "CONFIG_b4c2e8f1"
maxmemory 2gb
maxmemory-policy allkeys-lru
```
## Container Security
### Runtime Hardening
If deploying CaseBender with Docker or Kubernetes:
**Docker Compose:**
```yaml theme={null}
services:
web:
image: casebender/web@sha256:RELEASE_DIGEST
read_only: true
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
tmpfs:
- /tmp
deploy:
resources:
limits:
cpus: '2.0'
memory: 4G
reservations:
cpus: '0.5'
memory: 1G
```
**Kubernetes:**
```yaml theme={null}
securityContext:
runAsNonRoot: true
runAsUser: 1001
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "500m"
memory: "1Gi"
```
### Image Verification
Before deploying, verify container image signatures:
```bash theme={null}
# Verify image signature
cosign verify \
--certificate-identity-regexp="github.com/casebender" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
REGISTRY/casebender/web:TAG
# Verify SBOM attestation
cosign verify-attestation \
--type cyclonedx \
--certificate-identity-regexp="github.com/casebender" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
REGISTRY/casebender/web:TAG
```
## Network Security
### Firewall Rules
| Source | Destination | Port | Protocol | Purpose |
| ------------- | ----------------- | -------------- | -------- | ------------------- |
| Internet | Load Balancer | 443 | HTTPS | User access |
| Load Balancer | Web/API/Ingestion | 3000/4000/4100 | HTTP | Application traffic |
| App Services | PostgreSQL | 5432 | TCP/TLS | Database |
| App Services | Redis | 6379 | TCP/TLS | Cache/Queue |
| App Services | Elasticsearch | 9200 | HTTPS | Search |
| App Services | SIEM | Varies | TCP/TLS | Audit forwarding |
### Recommendations
* Block all inbound traffic except port 443
* Use private networking for all inter-service communication
* Implement network segmentation between application and data tiers
* Enable network flow logging for forensic analysis
* Consider a Web Application Firewall (WAF) in front of the load balancer
### Outbound integration policy
CaseBender validates the final outbound destination, disallows redirects, and
rejects loopback, link-local, cloud metadata, private, and non-HTTPS
destinations by default. On-premises integrations may be explicitly allowlisted
by exact hostname:
```bash theme={null}
CASEBENDER_PRIVATE_EGRESS_ALLOWLIST=siem.internal.example
```
Do not use wildcards or broad private-network ranges. Keep cloud metadata and
orchestrator control-plane addresses blocked. Restrict container egress at the
firewall as a second control.
## Monitoring
### Health Check Endpoints
CaseBender exposes health check endpoints for monitoring:
| Endpoint | Purpose | Response |
| -------------- | --------------------------------------- | ------------------- |
| `/api/health` | Web process health | Minimal JSON status |
| `/health` | API process health (internal) | Minimal JSON status |
| `/health/live` | Ingestion/processor liveness (internal) | Minimal status |
Detailed dependency, queue, credential, or configuration data must not be
exposed by public health endpoints.
### Recommended Monitoring
| Metric | Alert Threshold | Tool |
| --------------------- | ---------------------- | ------------------------------- |
| Health check failures | 3 consecutive failures | Prometheus, Datadog, CloudWatch |
| Response time (P95) | > 2 seconds | APM tool |
| Error rate (5xx) | > 1% of requests | Log aggregation |
| CPU utilization | > 80% sustained | Infrastructure monitoring |
| Memory utilization | > 85% | Infrastructure monitoring |
| Disk usage | > 80% | Infrastructure monitoring |
| Certificate expiry | \< 30 days | Certificate monitoring |
| Backup age | > 24 hours | Backup monitoring |
### Log Aggregation
Collect and centralize logs from all CaseBender services:
* Application logs (structured JSON)
* Access logs (reverse proxy)
* Database logs (PostgreSQL)
* Redis logs
* Container runtime logs
Use a log aggregation solution (ELK, Loki, Datadog, Splunk) to centralize, search, and alert on log data.
Never log authorization headers, API keys, webhook signing secrets, activation
codes, license signing keys, full proxy URLs, or integration request bodies.
Apply equivalent redaction in the log collector.
## Backup and Recovery
### Backup Strategy
| Component | Frequency | Retention | Method |
| ------------- | ------------------------------- | --------- | --------------------------- |
| PostgreSQL | Daily (full) + Continuous (WAL) | 30 days | pg\_dump + WAL archiving |
| Redis | Hourly (AOF) | 7 days | AOF persistence + snapshots |
| Elasticsearch | Daily | 14 days | Snapshot and restore |
| Configuration | On change | 90 days | Version control |
### Recovery Targets
| Metric | Target | Description |
| ---------------------------------- | ---------- | ---------------------------- |
| **RPO** (Recovery Point Objective) | \< 1 hour | Maximum acceptable data loss |
| **RTO** (Recovery Time Objective) | \< 4 hours | Maximum acceptable downtime |
### Recovery Testing
* Test database restoration quarterly
* Test full environment recovery annually
* Document recovery procedures and keep them updated
* Conduct tabletop exercises for disaster scenarios
## Related Documentation
* [Security Architecture](/en/security/architecture) — Platform security design
* [Supply Chain Security](/en/security/supply-chain) — Container image verification
* [Deployment Overview](/en/deployment/overview) — Platform deployment guides
# Independent Penetration Test Scope
Source: https://docs.casebender.com/en/security/penetration-test-scope
Rules of engagement and minimum coverage for an independent authenticated CaseBender security assessment.
## Objective
Commission an independent, authenticated penetration test of the CaseBender application, APIs, integrations, and supported on-premise deployment. The engagement must produce an evidence-backed report, remediation verification, and a retest letter suitable for customer due diligence.
## In Scope
* Web application and REST/tRPC APIs
* Administrative, analyst, read-only, and deliberately cross-tenant test identities
* Organization and team boundaries, RBAC, object-level authorization, and invitation flows
* Authentication, MFA, sessions, password reset, SSO, and account recovery
* Case, alert, observable, evidence, task, workflow, playbook, and reporting operations
* File upload, archive, document, image, JSON, XML, CSV, and other parser paths
* Outbound integrations, webhook callbacks, HTTP actions, URL enrichment, and SSRF controls
* Secrets, connector credentials, license keys, logs, exports, and error responses
* Audit-event integrity, attribution, ordering, deletion resistance, and privileged changes
* Docker Compose and Kubernetes deployment defaults, service exposure, container privileges, and secrets handling
* Published container images, SBOMs, provenance attestations, and signature verification
## Required Test Cases
1. Attempt horizontal and vertical privilege escalation across every identifier-bearing API.
2. Validate tenant isolation with paired organizations and intentionally overlapping object names.
3. Test mass assignment, unsafe filtering, pagination abuse, race conditions, and replay.
4. Exercise stored, reflected, and DOM XSS plus SQL/NoSQL/command/template injection.
5. Test SSRF with redirects, DNS rebinding, IPv4/IPv6 variants, metadata endpoints, and alternate URL encodings.
6. Fuzz uploads and parsers for traversal, decompression bombs, polyglots, XXE, and malicious filenames.
7. Validate CSRF, CORS, cookie attributes, session rotation, logout invalidation, and token lifetime.
8. Attempt audit suppression, tampering, log injection, and actions without attributable identity.
9. Review default network boundaries, non-root execution, writable paths, capabilities, and exposed management services.
10. Confirm no credentials or customer data appear in client bundles, images, logs, crash output, or build attestations.
## Rules of Engagement
* Use a dedicated production-like environment with synthetic data only.
* Provide written authorization, source IPs, test window, emergency contacts, and stop conditions.
* Permit authenticated testing and safe proof-of-concept exploitation; prohibit destructive persistence and denial-of-service unless separately approved.
* Record tool versions, timestamps, affected release digest, test identities, and complete reproduction steps.
* Notify the CaseBender security contact immediately for Critical findings or evidence of cross-tenant access.
## Deliverables and Acceptance
* Executive and technical reports with CVSS, business impact, evidence, and remediation guidance
* Coverage matrix mapping every in-scope area to tests performed and outcomes
* Explicit limitations and untested areas
* CaseBender triage response with owner and SLA for every finding
* Independent retest of all Critical and High findings
* Signed retest letter identifying the tested release and remaining accepted risks
The engagement is complete only after the retest artifacts are stored in the security evidence register and customer-facing claims are updated to match the verified result.
# Security Assurance Program
Source: https://docs.casebender.com/en/security/security-assurance
How CaseBender tests changes, blocks security regressions, protects release artifacts, and communicates assurance evidence to customers.
## Purpose
CaseBender is used by security teams, so product security is treated as a release requirement rather than a one-time checklist. The Security Assurance Program combines protected development workflows, automated security testing, container and dependency controls, release provenance, documented exceptions, and independent assessment planning.
This section explains:
* which controls run automatically;
* which findings block a change or release;
* what evidence each control produces;
* how exceptions are governed;
* what customers can verify independently; and
* where automated assurance stops.
Security assurance reduces risk; it does not prove that software is vulnerability-free. Workflow badges, scanner reports, SBOMs, and signatures are evidence of specific controls, not security certifications or substitutes for an independent penetration test.
## Assurance at a Glance
Pull requests to protected branches pass an aggregate security gate before merge.
Secrets, source code, dependencies, licenses, infrastructure, and all service images are checked using independent tools.
Release workflows generate SBOMs, provenance, immutable digests, and cryptographic signatures.
Customers can identify the evidence associated with a commit, image digest, or release.
## Secure Change Lifecycle
Every proposed change follows the same high-level lifecycle:
```text theme={null}
Developer change
→ Pull request
→ Build and functional checks
→ Parallel security controls
→ Aggregate Security Gate
→ Protected-branch review and merge
→ Pre-publish image scan
→ Digest-based publication and signing
→ Deployment readiness verification
→ Scheduled reassessment
```
Controls are deliberately layered. For example, dependency risk is evaluated through both the package-manager advisory database and Trivy; container images are scanned after they are built; and deterministic negative controls verify that secret and SAST scanners still reject known-bad fixtures.
## When Controls Run
| Event | Assurance activity |
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Pull request to `main` or `production` | Full source, dependency, license, IaC, Dockerfile, and seven-image security gate |
| Push to `main` | Security gate, SBOM generation, and main-branch artifact workflows |
| Published container build | Pre-publish vulnerability scan, immutable digest capture, signature creation, and signature verification |
| Weekly schedule | Full security workflow and authenticated OWASP ZAP staging scan when the required target and test identity are configured |
| Dependency update | The same pull-request gates apply; GitHub Dependency Review is additionally enforced where repository licensing enables it |
The workflow definition, not this page, is the final technical source for exact trigger and tool configuration. Authorized repository reviewers can inspect the [Security Scan workflow](https://github.com/casebender/webapp/actions/workflows/security-scan.yml); public customers should use the release-specific evidence described in the [Security Evidence Guide](/en/security/security-evidence).
## Merge-Blocking Security Gate
The aggregate Security Gate requires the following jobs to succeed on pull requests and pushes:
| Control | Scope | Blocking condition |
| ------------------------ | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Gitleaks | Current source and full Git history | Detected secret pattern |
| Trivy filesystem scan | Repository and dependency manifests | Unaccepted HIGH or CRITICAL vulnerability with a fix available |
| Trivy container scan | Web, API, ingestion, worker, workflow processor, MISP processor, and search sync images | Unaccepted HIGH or CRITICAL image vulnerability with a fix available |
| Hadolint | All seven Dockerfiles | Dockerfile policy violation |
| Trivy IaC scan | Dockerfiles and Kubernetes configuration | HIGH or CRITICAL security misconfiguration |
| ESLint security rules | Web TypeScript and JavaScript | Security rule error |
| Semgrep | TypeScript, Next.js, OWASP, injection, XSS, secrets, and security-audit rules | ERROR-severity finding or scanner failure |
| License policy | Repository dependencies | Unapproved blocking license or malformed/empty report |
| `pnpm audit` | Production dependencies | HIGH or CRITICAL advisory |
| SBOM generation | Full workspace | CycloneDX generation failure |
| Security control tests | Generated secret and unsafe-code fixtures | Scanner fails to reject a known-bad fixture |
| GitHub Dependency Review | Pull-request dependency delta, when licensed | New HIGH/CRITICAL vulnerability or denied license |
Scanner result uploads may be best-effort when GitHub Code Security is not licensed, but the underlying local scan remains blocking. Reports are also preserved as workflow artifacts so the gate does not depend on SARIF ingestion.
## Dynamic Security Testing
The weekly DAST job uses OWASP ZAP against a dedicated staging deployment. Before active testing starts, CI verifies:
1. the target is not a placeholder, localhost, or loopback address;
2. the response identifies a CaseBender web deployment;
3. the configured test identity produces an authenticated session; and
4. the authentication header is supplied through masked repository secrets.
The scan performs authenticated active testing and preserves its report. Missing targets or credentials cause the DAST job to fail rather than silently scanning an irrelevant page.
DAST coverage is constrained by the routes and state reachable by the test identity. It does not replace manual authorization, tenant-isolation, workflow-abuse, parser, or integration testing.
## Container Assurance
CaseBender currently produces seven service images. Each production Dockerfile uses a multi-stage build and a non-root runtime user. The container assurance path includes:
* Dockerfile linting;
* production dependency pruning;
* vulnerability scanning before publication;
* embedded-secret detection through image scanning;
* immutable digest selection after publication;
* keyless Cosign signing through GitHub's OIDC identity; and
* signature verification against the exact published digest.
Docker Hub and GitHub Container Registry workflows sign the digest that customers pull rather than relying only on mutable tags such as `latest`.
## Software Supply Chain Evidence
Release workflows generate several complementary records:
* **CycloneDX SBOM** — package and component inventory for dependency analysis;
* **BuildKit SBOM and provenance** — build metadata emitted with container builds;
* **Cosign signature** — cryptographic identity bound to an immutable image digest;
* **SBOM attestation** — signed association between an image and its component inventory;
* **SLSA-format provenance document** — source revision, workflow identity, and invocation metadata; and
* **Scanner reports** — SARIF or JSON output retained by the applicable workflow.
The standalone SLSA-format document is signed build metadata. Its current `subject` is empty, so it is not cryptographically bound to the seven image digests and must not be represented as artifact-level provenance or an independent SLSA certification.
## Vulnerability Handling
Findings are triaged according to severity, exploitability, affected deployment mode, exposure, and patch availability. The default remediation targets documented by the project are:
| Severity | Target |
| -------- | -------- |
| Critical | 24 hours |
| High | 7 days |
| Medium | 30 days |
| Low | 90 days |
These are internal remediation targets, not contractual service levels unless incorporated into a customer agreement.
When immediate remediation is not possible, an exception must be narrow and reviewable. Current Trivy IaC exceptions are stored in `.trivyignore.yaml` and include the finding, affected path, justification, and expiry date. License exceptions are package-specific; the policy does not suppress a license identifier globally. The repository file should not be interpreted as a complete register for every category of accepted product risk.
## Tool and Workflow Integrity
The controls themselves are also protected:
* third-party GitHub Actions are pinned to immutable commit SHAs;
* important scanner binaries and container images are version or digest pinned;
* lockfile-based installs use `--frozen-lockfile`;
* security negative controls detect a scanner that unexpectedly stops rejecting known-bad input;
* current GitHub branch-protection settings reject direct updates that have not produced required status checks; this policy is administered outside the source repository; and
* aggregate jobs fail if a required security job is failed, cancelled, or unexpectedly skipped.
### Supplementary Malware Heuristic
A separate post-merge workflow monitors changes to Next.js and PostCSS configuration files on `main` for known malicious npm supply-chain patterns and can create an automated revert. This is a narrow, pattern-based recovery control. It is not a pull-request gate, antivirus engine, EDR control, or comprehensive malware scan.
## Customer Responsibilities
CaseBender is deployable on customer-managed infrastructure. Product assurance does not replace secure operation of that environment. Customers remain responsible for:
* TLS certificates, ingress, firewall, and network segmentation;
* identity-provider, MFA, and role configuration;
* database, Redis, object-storage, and search-service hardening;
* secret rotation and access to deployment credentials;
* backups, monitoring, retention, and incident response;
* applying supported updates and reviewing release notes; and
* validating controls against their regulatory and threat environment.
See the [Deployment Hardening Guide](/en/security/hardening-guide) for operational recommendations.
## Current Assurance Boundaries
As of July 2026:
* automated SAST, SCA, secret, license, IaC, container, SBOM, signing, and provenance workflows are implemented;
* authenticated staging DAST is configured in CI but depends on a maintained staging target and test identity;
* GitHub-hosted SARIF and Dependency Review features depend on repository licensing, while local Trivy and package-audit gates remain available;
* no completed third-party penetration-test report or remediation retest letter is claimed; and
* compliance mappings describe control alignment, not an independent certification.
The proposed independent assessment scope is documented in [Independent Penetration Test Scope](/en/security/penetration-test-scope).
## Related Documentation
* [Code Security](/en/security/code-security) — scanner configuration, DAST, licenses, and vulnerability management
* [Supply Chain Security](/en/security/supply-chain) — dependencies, images, SBOMs, signing, and provenance
* [Security Evidence Guide](/en/security/security-evidence) — evidence types and how to interpret them
* [Security Architecture](/en/security/architecture) — application and deployment security design
* [Independent Penetration Test Scope](/en/security/penetration-test-scope) — planned manual assessment coverage
# Security Evidence Guide
Source: https://docs.casebender.com/en/security/security-evidence
A guide for customers reviewing CaseBender scanner reports, SBOMs, signatures, provenance, exceptions, and assessment status.
## Overview
Security evidence is most useful when it can be traced to the exact software a customer is evaluating. CaseBender identifies builds by Git commit and identifies container artifacts by immutable digest.
For an assurance review, begin with one of:
* a CaseBender release version;
* the Git commit SHA shown by the release;
* the digest of each deployed container image; or
* the workflow run that produced the artifacts.
Tags such as `latest` are convenient references but are not stable evidence identifiers.
## Evidence Catalog
| Evidence | What it demonstrates | Important limitation |
| ------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| Security Gate result | Required CI security jobs completed successfully for a revision | Covers configured automated controls only |
| Gitleaks report/log | No matching secret pattern remained in the scanned source and history | Cannot identify every possible credential format |
| Trivy filesystem SARIF | Dependency findings for the scanned repository state | Advisory databases and package detection change over time |
| Trivy container SARIF | OS and application findings in a built service image | Applies only to the scanned digest |
| Trivy IaC SARIF | Findings in Docker and Kubernetes configuration | Does not validate every runtime platform setting |
| Semgrep SARIF | Findings from configured source and taint-analysis rules | Rule coverage is not equivalent to manual code review |
| Dependency audit JSON | Production dependency advisories known to the package registry | Does not cover operating-system packages |
| License JSON and policy result | Detected licenses and package-specific policy decisions | Legal interpretation remains customer-specific |
| CycloneDX SBOM | Components detected for a repository or image | An SBOM is an inventory, not a vulnerability-free statement |
| Cosign signature | A workflow identity signed a specific image digest | Signature verification does not assess application behavior |
| SBOM attestation | A signed SBOM is associated with a specific image | The attestation is only as accurate as SBOM generation |
| SLSA-format provenance document | Source revision and build invocation metadata | Current `subject` is empty; it is not bound to an image digest or independently certified |
| OWASP ZAP report | Results from the authenticated staging routes reached by ZAP | Does not prove complete API or business-logic coverage |
| Exception record | A finding was intentionally scoped, justified, and given an expiry | Does not eliminate the underlying risk |
## Traceability Procedure
### 1. Record the deployed digest
Use the registry or container runtime to capture the immutable digest:
```bash theme={null}
docker image inspect IMAGE:TAG \
--format='{{index .RepoDigests 0}}'
```
Expected output resembles:
```text theme={null}
registry.example.com/casebender/web@sha256:...
```
### 2. Verify the signature
CaseBender release workflows use keyless Cosign signing backed by GitHub Actions OIDC:
```bash theme={null}
cosign verify \
--certificate-identity-regexp='https://github.com/casebender/webapp/' \
--certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
IMAGE@sha256:DIGEST
```
Verification should be performed against a digest, not only a tag. The registry channel and certificate identity must match the release documentation supplied with the artifact.
### 3. Verify provenance metadata
Review the provenance document for:
* repository and source revision;
* workflow identity and trigger;
* build timestamp and actor;
* the `subject` field and whether it identifies the artifact under review; and
* the attached signature and signing certificate.
The current standalone CaseBender provenance document has an empty `subject`. It can be verified as signed workflow metadata, but it cannot currently prove that a particular container digest was produced by that invocation. Use the registry digest, image signature, and image SBOM attestation for artifact-level traceability.
Verify the signed blob before relying on its content:
```bash theme={null}
cosign verify-blob \
--signature provenance.json.sig \
--certificate provenance.json.cert \
--certificate-identity-regexp='https://github.com/casebender/webapp/' \
--certificate-oidc-issuer='https://token.actions.githubusercontent.com' \
provenance.json
```
### 4. Review the SBOM
Use the SBOM to identify direct and transitive components relevant to your deployment. Customers may import CycloneDX JSON into their own vulnerability-management or software-asset tools.
An SBOM should be matched to the same commit or image digest under review. A repository-level SBOM and an image-level SBOM answer different questions and should not be treated as interchangeable.
### 5. Review security findings and exceptions
Confirm:
* the scan completed rather than being skipped;
* the report corresponds to the target revision or digest;
* the severity policy used by the workflow;
* whether unfixed findings were excluded by the scanner configuration;
* whether an exception applies to the exact finding and path; and
* whether the exception is still within its review period.
## Artifact Retention
Current workflow retention settings include:
* scanner and audit artifacts: generally 30 days;
* repository CycloneDX SBOM artifacts and signing material: 1,095 days; and
* registry signatures and attestations: retained with the applicable registry artifact, subject to registry lifecycle policy.
Retention in a customer's own environment is controlled by that customer. Customers with longer audit requirements should archive the evidence package received for each deployed release.
## Suggested Customer Evidence Package
For a release assurance review, the relevant package may include:
1. release identifier and commit SHA;
2. immutable digests for the deployed service images;
3. Security Gate workflow result;
4. container scan results for those digests;
5. CycloneDX SBOMs;
6. signature-verification output;
7. signed provenance and verification output;
8. applicable active exception records;
9. a vulnerability-remediation summary; and
10. the current penetration-testing status statement.
Availability may depend on repository permissions, registry channel, artifact-retention windows, and contractual disclosure terms. Raw reports can contain repository paths, dependency details, or infrastructure information and may require secure transfer or redaction.
## Interpreting a Successful Result
A green workflow means the configured jobs completed according to the policy encoded at that revision. It does not mean:
* no vulnerability exists;
* every application path was tested;
* all deployed infrastructure matches the scanned templates;
* every dependency is free of future advisories;
* a third party independently validated the result; or
* the release is certified against a compliance framework.
For higher-assurance deployments, combine automated evidence with architecture review, customer-environment hardening, threat modeling, and independent manual testing.
## Penetration-Test Evidence
CaseBender does not currently claim a completed third-party penetration-test report or remediation retest letter. Automated ZAP testing and the in-product penetration-test management capability are not substitutes for that evidence.
The planned engagement, required tester qualifications, rules of engagement, and expected deliverables are documented in [Independent Penetration Test Scope](/en/security/penetration-test-scope).
## Reporting a Security Concern
Report suspected CaseBender vulnerabilities to [security@casebender.com](mailto:security@casebender.com). Include:
* affected version or image digest;
* deployment mode;
* reproducible steps;
* expected and observed behavior;
* potential impact; and
* any proof-of-concept material suitable for secure handling.
Do not include active credentials, customer data, or destructive exploit material in an initial unencrypted message.
## Related Documentation
* [Security Assurance Program](/en/security/security-assurance)
* [Code Security](/en/security/code-security)
* [Supply Chain Security](/en/security/supply-chain)
* [Deployment Hardening Guide](/en/security/hardening-guide)
# Supply Chain Security
Source: https://docs.casebender.com/en/security/supply-chain
How CaseBender secures its build pipeline with dependency management, container signing, SBOM generation, and SLSA provenance.
## Overview
CaseBender's supply-chain workflows combine dependency controls, image scanning, SBOM generation, digest-based signing, and provenance. Vulnerability gates run before publication; signing and attestation coverage depends on the registry channel and release workflow described below.
### Pipeline Workflows
| Pipeline | Runs On |
| -------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| [Security Scan](https://github.com/casebender/webapp/actions/workflows/security-scan.yml) | Every pull request to `main` or `production`, push to `main`, and weekly schedule |
| [Supply Chain Verify](https://github.com/casebender/webapp/actions/workflows/supply-chain-verify.yml) | Every pull request and push to `main` or `production` |
| [Main Image Build](https://github.com/casebender/webapp/actions/workflows/build-all-images-publish-deploy.yml) | Relevant pushes to `main` and manual edge builds |
| [On-Premises Release](https://github.com/casebender/webapp/actions/workflows/release-onprem.yml) | SemVer tag pushes and recovery runs for existing release tags |
GitHub workflow badge images are not publicly readable for this private repository and return `404 Not Found` when embedded without an authorized GitHub session. Authorized reviewers can use the links above; public assurance should rely on release-specific signatures, SBOMs, provenance metadata, and provided reports.
Stable publication starts from a protected SemVer Git tag. Manual workflow
dispatch is recovery-only: it must run from `main`, requires an existing release
tag, reuses that tag's signed candidate digests, and cannot create a new release
from arbitrary branch contents.
## Dependency Management
### Resolution Control
The lockfile records exact resolved dependency versions, while some package manifests retain compatible version ranges:
* **`save-exact=true`** in `.npmrc` makes newly added dependencies exact by default
* **`strict-peer-dependencies=false`** is currently required for documented React 19 peer-range incompatibilities; CI still reports peer warnings
* **`pnpm install --frozen-lockfile`** in all Dockerfiles ensures builds use exactly the versions in the lockfile
* **Node.js version pinned** via `.nvmrc` and `.node-version` (Node.js 20.x)
* **pnpm version pinned** in Dockerfiles to prevent tool-level supply chain attacks
### Automated Dependency Updates
[Dependabot](https://docs.github.com/en/code-security/dependabot) monitors for updates across three ecosystems:
| Ecosystem | Schedule | Scope |
| ------------------ | ------------------ | ---------------------------------------------------------- |
| **npm** | Weekly (Monday) | Production deps, dev deps, OpenTelemetry, Prisma (grouped) |
| **Docker** | Weekly (Tuesday) | Base images for all 8 services |
| **GitHub Actions** | Weekly (Wednesday) | All CI/CD workflow action versions |
Dependabot PRs are:
* Automatically labeled with `dependencies` and `security`
* Blocked from merging if they introduce HIGH or CRITICAL vulnerabilities
* Reviewed by the security team before merge
### Dependency Review
When GitHub Code Security is licensed and `ENABLE_CODE_SCANNING` is enabled, pull-request dependency deltas are checked for:
* New dependencies with known vulnerabilities (HIGH/CRITICAL blocked)
* Dependencies with forbidden licenses (copyleft licenses blocked)
* Dependencies with no license (flagged for review)
* Pre-release dependencies (documented and tracked)
Without that repository feature, the merge-blocking Trivy filesystem scan, production `pnpm audit`, and license-policy job remain active.
### Approved Component Registry
CaseBender maintains a documented registry of approved third-party components organized by risk tier:
| Tier | Risk Level | Examples | Review Frequency |
| ---------- | ---------- | --------------------------------------- | --------------------- |
| **Tier 1** | Critical | next-auth, prisma, bcrypt, jose | Every update reviewed |
| **Tier 2** | High | tRPC, zod, bullmq, ioredis | Monthly review |
| **Tier 3** | Medium | shadcn/ui, lucide-react, tailwindcss | Quarterly review |
| **Tier 4** | Low | eslint, prettier, typescript (dev-only) | Annual review |
## Container Security
### Build Hardening
Every CaseBender container image follows security best practices:
```
Multi-Stage Build → Non-Root User → Alpine Base → Pinned Versions → Frozen Lockfile → No Secrets
```
* **Multi-stage builds**: Build dependencies (compilers, dev tools) are excluded from production images
* **Non-root users**: Each service runs as a dedicated non-root user inside the container
* **Alpine Linux**: Minimal base images reduce attack surface
* **Pinned tool versions**: System packages and global tools are version-pinned
* **No embedded secrets**: All secrets are injected at runtime
### Container Scanning
Every service image built by the pull-request security workflow is scanned locally with [Trivy](https://trivy.dev/) for:
* **OS vulnerabilities**: CVEs in Alpine packages
* **Application vulnerabilities**: CVEs in Node.js dependencies
* **Misconfigurations**: Dockerfile best practice violations
* **Secrets**: Embedded credentials or API keys
Scans run on every PR and block merges if CRITICAL or HIGH vulnerabilities are found.
## Image Signing
CaseBender uses [Cosign](https://docs.sigstore.dev/cosign/overview/) keyless signing through [Sigstore](https://www.sigstore.dev/) for customer-facing Docker Hub publications. Main builds publish SHA and `edge` tags. Only the release workflow can promote stable SemVer and `latest` tags.
### Signed Images
| Image | Signed publication channels |
| ------------------------------- | ------------------------------------------- |
| `casebender/casebender` | Docker Hub main and stable release channels |
| `casebender/api` | Docker Hub main and stable release channels |
| `casebender/ingestion` | Docker Hub main and stable release channels |
| `casebender/worker` | Docker Hub main and stable release channels |
| `casebender/workflow-processor` | Docker Hub main and stable release channels |
| `casebender/connector-worker` | Docker Hub main and stable release channels |
| `casebender/misp-processor` | Docker Hub main and stable release channels |
| `casebender/search-sync` | Docker Hub main and stable release channels |
Google Artifact Registry is used by the managed Cloud Run deployment workflow. Its signature-verification step is currently report-only during the SEC-019 rollout and must not be represented as a blocking signed-deployment gate.
### Verification
Across the signed publication workflows, controls include:
1. **Signature Verification**: Cosign verifies the image signature against the Sigstore transparency log
2. **SBOM and provenance attestations**: BuildKit binds generated attestations to the image digest
3. **Vulnerability Scan**: Final Trivy scan for CRITICAL vulnerabilities
You can verify any CaseBender image signature yourself using:
```bash theme={null}
cosign verify \
--certificate-identity="https://github.com/casebender/webapp/.github/workflows/release-onprem.yml@refs/tags/vX.Y.Z" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
casebender/casebender@sha256:DIGEST
```
## SBOM (Software Bill of Materials)
Every release image includes a BuildKit-generated SBOM attestation:
* **Generated by**: Docker BuildKit
* **Bound to**: The immutable image digest
* **Protected by**: Registry provenance plus the digest's Cosign signature
* **Release evidence**: The customer bundle records all seven signed digests
The SBOM documents every component in the container image:
* Node.js runtime version
* All npm packages with exact versions
* Alpine Linux packages
* System libraries and their versions
## SLSA Provenance
Docker BuildKit emits artifact-bound provenance (`mode=max`) for each published
image. This replaces the former standalone metadata document whose subject was
not bound to an image.
### What Provenance Documents
| Field | Content |
| ---------------- | ------------------------------------------- |
| **Source** | Git commit SHA, repository URL, branch |
| **Builder** | GitHub Actions workflow, runner environment |
| **Build Config** | Workflow file path, trigger event |
| **Subject** | Immutable container image digest |
| **Metadata** | Build timestamp, actor, invocation ID |
### Provenance Security
* Provenance and SBOM attestations are emitted during the image build
* Cosign signs the exact digest after vulnerability scanning
* The release workflow verifies every signature before tag promotion
* The signed customer bundle contains a manifest mapping each service to its digest
## Pre-Deployment Verification
The Cloud deployment workflow runs reproducibility and image-verification checks before deployment. Their current enforcement differs:
### Reproducible Build Verification
This is a required job and checks that the build environment is consistent:
* Lockfile integrity (`pnpm-lock.yaml` exists and is valid)
* Node.js version matches expected version (20.x)
* pnpm version matches expected version (9.15.0)
* `.npmrc` security settings are present (`save-exact`, `audit`)
* No suspicious postinstall scripts in dependencies
* Version pinning files (`.nvmrc`, `.node-version`) are present
### Image Verification
The main and on-premises release workflows enforce image authenticity and safety
before their public aliases move:
* Hadolint Dockerfile policy
* Trivy CRITICAL/HIGH vulnerability gate
* BuildKit SBOM and provenance attestations
* Cosign digest signing and exact workflow-identity verification
* post-promotion digest verification
## Compliance Mapping
| Control | Framework | CaseBender Implementation |
| ---------------------------- | ----------- | ----------------------------------------------------------- |
| SR-3 Supply Chain Protection | CMMC | Dependency pinning, lockfile integrity, reproducible builds |
| SR-4 Provenance | CMMC | SLSA provenance, image signing, SBOM |
| SR-11 Component Authenticity | CMMC | Cosign signature verification, Sigstore transparency |
| SI-7 Software Integrity | NIST 800-53 | Image signing, SBOM attestation, build verification |
| CM-2 Baseline Configuration | NIST 800-53 | Pinned versions, frozen lockfiles, reproducible builds |
| CM-6 Configuration Settings | NIST 800-53 | `.npmrc` hardening, Dockerfile best practices |
## Related Documentation
* [Security Assurance Program](/en/security/security-assurance) — Control lifecycle, enforcement, and assurance boundaries
* [Code Security](/en/security/code-security) — SAST, DAST, and vulnerability management
* [Security Evidence Guide](/en/security/security-evidence) — Digest traceability, signature verification, and evidence interpretation
* [Security Overview](/en/security/overview) — Live pipeline status badges
* [Hardening Guide](/en/security/hardening-guide) — Deployment security recommendations
# Delete API Key
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/delete
DELETE /api-keys/{id}
Delete an API key
# Get API Key by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/get-by-id
GET /api-keys/{id}
Retrieve a specific API key
# Rotate API Key
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/rotate
POST /api-keys/{id}/rotate
Rotate an API key to generate new credentials
# Get Available Scopes
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/scopes
GET /api-keys/scopes
Get list of available API scopes
# Get API Key Usage Stats
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/stats
GET /api-keys/{id}/stats
Get usage statistics for an API key
# Update API Key
Source: https://docs.casebender.com/en/api-reference/endpoint/api-keys/update
PUT /api-keys/{id}
Update an existing API key
# Get Alert Audit History
Source: https://docs.casebender.com/en/api-reference/endpoint/audit/alert-history
GET /audit/alert/{alertId}
Get the complete audit history for a specific alert
# Get Audit Record
Source: https://docs.casebender.com/en/api-reference/endpoint/audit/get-by-id
GET /audit/{id}
Retrieve a specific audit record
# List Audit Records
Source: https://docs.casebender.com/en/api-reference/endpoint/audit/list
GET /audit
List audit records with optional filters
# Get Audit Statuses
Source: https://docs.casebender.com/en/api-reference/endpoint/audit/statuses
GET /audit/statuses
Get list of available audit statuses
# Bulk Assign Alerts
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/alerts-assign
POST /bulk/alerts/assign
Bulk assign alerts to a user (FUNC-014)
# Bulk Delete Alerts
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/alerts-delete
DELETE /bulk/alerts
Bulk delete multiple alerts (soft delete) (FUNC-014)
# Bulk Merge Alerts
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/alerts-merge
POST /bulk/alerts/merge
Bulk merge alerts into a target case (FUNC-014)
# Bulk Change Alert Status
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/alerts-status
POST /bulk/alerts/status
Bulk change alert status (FUNC-014)
# Bulk Update Alerts
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/alerts-update
POST /bulk/alerts
Bulk update multiple alerts (FUNC-014)
# Bulk Assign Cases
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/cases-assign
POST /bulk/cases/assign
Bulk assign cases to a user and/or teams (FUNC-014)
# Bulk Delete Cases
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/cases-delete
DELETE /bulk/cases
Bulk delete multiple cases (soft delete) (FUNC-014)
# Bulk Change Case Status
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/cases-status
POST /bulk/cases/status
Bulk change case status with mandatory task validation (FUNC-014, FUNC-031)
# Bulk Update Case Tags
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/cases-tags
POST /bulk/cases/tags
Bulk add/remove/set tags on cases (FUNC-014)
# Bulk Set Case TLP
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/cases-tlp
POST /bulk/cases/tlp
Bulk set TLP/PAP classification on cases with optional propagation (FUNC-014, FUNC-044)
# Bulk Update Cases
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/cases-update
POST /bulk/cases
Bulk update multiple cases (FUNC-014)
# Bulk Delete Observables
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/observables-delete
DELETE /bulk/observables
Bulk delete multiple observables (FUNC-014)
# Bulk Set Observable IOC
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/observables-ioc
POST /bulk/observables/ioc
Bulk set IOC flag on observables (FUNC-014)
# Bulk Update Observables
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/observables-update
POST /bulk/observables
Bulk update multiple observables (FUNC-014)
# Bulk Assign Tasks
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/tasks-assign
POST /bulk/tasks/assign
Bulk assign tasks to a user and/or teams (FUNC-014, FUNC-045)
# Bulk Delete Tasks
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/tasks-delete
DELETE /bulk/tasks
Bulk delete multiple tasks (soft delete) (FUNC-014)
# Bulk Set Task Mandatory
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/tasks-mandatory
POST /bulk/tasks/mandatory
Bulk set mandatory flag on tasks (FUNC-014, FUNC-031)
# Bulk Update Tasks
Source: https://docs.casebender.com/en/api-reference/endpoint/bulk/tasks-update
POST /bulk/tasks
Bulk update multiple tasks (FUNC-014)
# Create Custom Field
Source: https://docs.casebender.com/en/api-reference/endpoint/custom-fields/create
POST /custom-fields
Create a new custom field definition (admin only)
# Delete Custom Field
Source: https://docs.casebender.com/en/api-reference/endpoint/custom-fields/delete
DELETE /custom-fields/{id}
Delete a custom field definition (admin only)
# Get Custom Field by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/custom-fields/get-by-id
GET /custom-fields/{id}
Retrieve a specific custom field definition
# List Custom Fields
Source: https://docs.casebender.com/en/api-reference/endpoint/custom-fields/list
GET /custom-fields
List all custom field definitions
# Update Custom Field
Source: https://docs.casebender.com/en/api-reference/endpoint/custom-fields/update
PUT /custom-fields/{id}
Update an existing custom field definition (admin only)
# Create Integration
Source: https://docs.casebender.com/en/api-reference/endpoint/integrations/create
POST /integrations
Create a new integration configuration (admin only)
# Delete Integration
Source: https://docs.casebender.com/en/api-reference/endpoint/integrations/delete
DELETE /integrations/{id}
Delete an integration configuration (admin only)
# Get Integration by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/integrations/get-by-id
GET /integrations/{id}
Retrieve a specific integration configuration
# List Integrations
Source: https://docs.casebender.com/en/api-reference/endpoint/integrations/list
GET /integrations
List all configured integrations
# List Integration Types
Source: https://docs.casebender.com/en/api-reference/endpoint/integrations/types
GET /integrations/types
Get all available integration types
# Update Integration
Source: https://docs.casebender.com/en/api-reference/endpoint/integrations/update
PUT /integrations/{id}
Update an existing integration configuration (admin only)
# Get Alerts by Source
Source: https://docs.casebender.com/en/api-reference/endpoint/metrics/alerts-source
GET /metrics/alerts/source
Get alert count grouped by source
# Get Cases by Severity
Source: https://docs.casebender.com/en/api-reference/endpoint/metrics/cases-severity
GET /metrics/cases/severity
Get case count grouped by severity level
# Get Cases by Status
Source: https://docs.casebender.com/en/api-reference/endpoint/metrics/cases-status
GET /metrics/cases/status
Get case count grouped by status
# Get Case Trend
Source: https://docs.casebender.com/en/api-reference/endpoint/metrics/cases-trend
GET /metrics/cases/trend
Get case creation trend over time
# Get Dashboard Metrics
Source: https://docs.casebender.com/en/api-reference/endpoint/metrics/dashboard
GET /metrics/dashboard
Get overview metrics for the dashboard
# Get MTTR
Source: https://docs.casebender.com/en/api-reference/endpoint/metrics/mttr
GET /metrics/mttr
Get Mean Time To Resolve for cases
# Get SLA Configuration
Source: https://docs.casebender.com/en/api-reference/endpoint/sla/config
GET /sla/config
Get the global SLA configuration
# Get SLA History
Source: https://docs.casebender.com/en/api-reference/endpoint/sla/history
GET /sla/history/{entityType}/{entityId}
Get the SLA status history for a case or alert
# Get SLA Status
Source: https://docs.casebender.com/en/api-reference/endpoint/sla/status
GET /sla/status/{entityType}/{entityId}
Get the current SLA status for a case or alert
# Get SLA Template
Source: https://docs.casebender.com/en/api-reference/endpoint/sla/template-by-id
GET /sla/templates/{id}
Get a specific SLA template by ID
# List SLA Templates
Source: https://docs.casebender.com/en/api-reference/endpoint/sla/templates
GET /sla/templates
Get all SLA templates
# Create Template
Source: https://docs.casebender.com/en/api-reference/endpoint/templates/create
POST /templates
Create a new template
# Delete Template
Source: https://docs.casebender.com/en/api-reference/endpoint/templates/delete
DELETE /templates/{id}
Delete a template
# Get Template by ID
Source: https://docs.casebender.com/en/api-reference/endpoint/templates/get-by-id
GET /templates/{id}
Retrieve a specific template
# List Templates
Source: https://docs.casebender.com/en/api-reference/endpoint/templates/list
GET /templates
List all templates with optional entity type filter
# Update Template
Source: https://docs.casebender.com/en/api-reference/endpoint/templates/update
PUT /templates/{id}
Update an existing template
# Get TLP Audit Logs
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/audit-logs
GET /tlp/audit-logs
Get TLP access and change audit logs
# List TLP Change Requests
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/change-requests
GET /tlp/change-requests
List pending TLP change requests awaiting approval
# Check TLP Access
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/check-access
POST /tlp/check-access
Check if the current user has TLP clearance to access an entity
# Get TLP Constants
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/constants
GET /tlp/constants
Get TLP level constants including labels, descriptions, and colors for UI rendering
# Get Entity TLP
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/entity-get
GET /tlp/entity/{type}/{id}
Get the TLP level for a specific entity (case, alert, task, etc.)
# Change Entity TLP
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/entity-update
PUT /tlp/entity/{type}/{id}
Change the TLP level for an entity. May require approval for high TLP levels.
# Process TLP Change Request
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/process-change-request
POST /tlp/change-requests/{id}/process
Approve or reject a pending TLP change request
# Propagate TLP
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/propagate
POST /tlp/propagate
Propagate TLP from a parent entity to its children
# Get User Max TLP
Source: https://docs.casebender.com/en/api-reference/endpoint/tlp/user-max
GET /tlp/user/max
Get the maximum TLP level the current user can access
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.
# Migrate a Legacy Docker Compose Installation
Source: https://docs.casebender.com/en/deployment/legacy-compose-migration
Move an existing app/db/MinIO installation to the signed CaseBender release bundle without losing data, attachments, credentials, or audit integrity.
# Migrate a legacy Docker Compose installation
Use this guide when the existing installation has a `docker-compose.yml` with
services such as `app`, `db`, and `minio`, or when it has historically been
updated with `docker compose pull`.
This is a one-time layout migration. It is not the same as a routine upgrade of
an installation that already uses `docker-compose.prod.yml` and
`./casebender upgrade`.
> Do not continue without a tested PostgreSQL restore and a verified attachment
> backup. Never run `./casebender init`, replace the existing `.env`, rotate an
> existing encryption or audit key, or run `docker compose down -v`.
## What changes
| Area | Legacy installation | Signed bundle |
| ------------------ | ---------------------------- | ------------------------------------------------------------ |
| Compose file | `docker-compose.yml` | `docker-compose.prod.yml` |
| Web service | `app` | `web` |
| PostgreSQL service | `db` | `postgres` |
| Image selection | Often `latest` | Version pinned by `release.env` |
| Upgrade command | Often raw Compose commands | `./casebender upgrade --version ` or `--offline` archive |
| Attachments | Usually MinIO in `miniodata` | Customer-owned external object storage |
| License key | Often `casebender_secret` | `LICENSE_SECRET_KEY` in `.env` |
| Audit integrity | May be absent | Stable `AUDIT_INTEGRITY_SECRET` in `.env` |
Docker Compose prefixes named volumes with the Compose project name. Keeping
the same installation directory and project name normally lets the signed
bundle reuse `pgdata` and `redis_data`. A different directory or `-p` value
creates different volume names and can make the application appear empty even
though the original data still exists.
## Phase 1: Inventory the existing installation
Run these commands from the existing installation directory:
```bash theme={null}
pwd
docker compose ls
docker compose config --services
docker compose config --volumes
docker compose ps
docker volume ls
```
Record:
* the Compose project name and installation directory;
* the exact CaseBender image tags;
* the PostgreSQL image and major version;
* the actual volume names mounted at `/var/lib/postgresql/data`,
`/data`, and `/app/apps/web/app/secret`;
* whether attachments use MinIO, local storage, or an external provider;
* the current database user, database name, and internal hostname;
* the current TLS and reverse-proxy configuration.
Inspect mounts without printing environment secrets:
```bash theme={null}
docker inspect "$(docker compose ps -q db)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
docker inspect "$(docker compose ps -q app)" \
--format '{{range .Mounts}}{{println .Name "->" .Destination}}{{end}}'
```
Check required keys by name only:
```bash theme={null}
for key in \
AUTH_SECRET AUTH_SALT NEXTAUTH_SECRET LICENSE_SECRET_KEY \
FIELD_ENCRYPTION_KEY CREDENTIAL_ENCRYPTION_KEY \
WEBHOOK_KEY_PEPPER CONNECTOR_BUNDLE_SIGNING_KEY OAUTH_BROKER_SECRET \
AUDIT_INTEGRITY_SECRET POSTGRES_PASSWORD REDIS_PASSWORD; do
if grep -q "^${key}=." .env; then
printf '%s: configured\n' "$key"
else
printf '%s: missing\n' "$key"
fi
done
```
Do not paste `.env`, license keys, encryption keys, database URLs, or backup
contents into tickets or chat.
## Phase 2: Create and test the recovery set
### PostgreSQL
Create a logical backup using the legacy `db` service:
```bash theme={null}
mkdir -p migration-backup
chmod 700 migration-backup
docker compose exec -T db \
sh -c 'pg_dump -Fc -U "$POSTGRES_USER" "${POSTGRES_DB:-casebender}"' \
> "migration-backup/casebender-$(date +%F).dump"
test -s "migration-backup/casebender-$(date +%F).dump"
docker run --rm -i postgres:17 pg_restore --list \
< "migration-backup/casebender-$(date +%F).dump" >/dev/null
```
The final proof is a restore into an isolated staging database followed by
application validation. Listing the archive is not a restore rehearsal.
Record baseline counts for users, organizations, cases, alerts, tasks,
attachments, evidence, and audit records. Use approved read-only queries for
the deployed schema.
### Configuration, TLS, and secrets
```bash theme={null}
cp -p .env "migration-backup/.env.$(date +%F)"
cp -p docker-compose.yml "migration-backup/docker-compose.yml.$(date +%F)"
cp -p nginx.conf "migration-backup/nginx.conf.$(date +%F)" 2>/dev/null || true
```
Store the backup outside the Docker host in the approved encrypted recovery
system. Include:
* `.env`;
* TLS certificates, private keys, and custom trust stores;
* the exact license secret and license blob;
* field and credential encryption keys;
* webhook, connector-signing, OAuth, authentication, and audit secrets;
* integration configuration and proxy/egress settings;
* the current Compose file and image inventory.
If `LICENSE_SECRET_KEY` is absent from `.env`, preserve the existing value
before stopping `app`:
```bash theme={null}
umask 077
docker compose exec -T app \
sh -c 'cat /app/apps/web/app/secret/license_secret_key' \
> migration-backup/license_secret_key
test -s migration-backup/license_secret_key
```
Transfer that value into the protected `LICENSE_SECRET_KEY` entry during the
environment transformation. Do not print it.
### Attachments
If the legacy configuration identifies the native MinIO provider, back up the
bucket through the S3/MinIO API. A
tarball or direct copy of MinIO's internal `miniodata` layout is a disaster
recovery snapshot, not a valid local-storage migration.
Keep both:
1. a snapshot or archive of the original `miniodata` volume; and
2. an object-level export made with `mc mirror` or your approved S3 backup
process.
Compare the exported object count and size with the source, then download
several known case attachments and evidence files from the rehearsal system.
## Phase 3: Check alert-promotion compatibility
The new release enables alert-to-case promotion by default. Keep it explicitly
disabled during a legacy-data migration:
```env theme={null}
ENTERPRISE_ALERT_PROMOTION=disabled
```
Check the schema and legacy observable parentage:
```sql theme={null}
SELECT to_regclass('"AlertPromotionOperation"') AS promotion_table;
SELECT count(*) AS dual_parent_observables
FROM "Observable"
WHERE "alertId" IS NOT NULL
AND "caseId" IS NOT NULL;
SELECT EXISTS (
SELECT 1
FROM pg_constraint
WHERE conname = 'Observable_at_most_one_parent_check'
) AS parent_constraint_installed;
```
Stop and use the release-specific promotion backfill procedure when:
* the promotion table is missing;
* any dual-parent observable exists; or
* backfill verification is not clean.
Do not enable promotion until the schema migration is applied, dual-parent
conflicts are zero, the parent constraint decision is verified, and the worker
outbox processor is healthy.
## Phase 4: Choose the attachment target
### Production target: qualified external storage
New production installations cannot select native MinIO or local storage.
Provision and qualify an existing AWS S3, GCS, Azure Blob, or exact-version
S3-compatible target according to the current release matrix. Prefer separate
`quarantine`, `records`, and `ephemeral` profiles in a mounted
`STORAGE_CONFIG_FILE`.
Use [Storage Migration](/en/deployment/storage-migration-runbook) to copy every
legacy object without changing its durable key, verify downloaded SHA-256, and
record exact source/destination versions in `StorageMigrationLedger`. Keep the
legacy MinIO service read-only as a migration/rollback source for the approved
window; it is not a supported new production destination.
Local `/data` may be used only in an isolated non-production rehearsal. Do not
use it as an intermediate production cutover or bypass production preflight.
Never copy MinIO's internal volume files directly into another provider.
Validate object counts, total bytes, exact versions, SHA-256, representative
downloads, scanner promotion, and delete/retention behavior in staging. Retain
the original `miniodata` snapshot and API-level export through the rollback
window. See [MinIO Lifecycle](/en/deployment/storage-minio-lifecycle).
## Phase 5: Prepare `.env` for the signed bundle
Start from the existing `.env`; do not start from `.env.example` and do not run
`./casebender init`.
| Variable | Migration action |
| ----------------------------- | -------------------------------------------------------------------------------------- |
| `POSTGRES_USER` | Preserve the existing user, commonly `superadmin` |
| `POSTGRES_PASSWORD` | Preserve exactly |
| `POSTGRES_DB` | Preserve exactly |
| `POSTGRES_PRISMA_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL` | Change only hostname `db` to `postgres` |
| `POSTGRES_URL_NON_POOLING` | Change only hostname `db` to `postgres` |
| `REDIS_PASSWORD` | Add a strong installation-specific value if absent |
| `REDIS_URL` | Use `redis://:@redis:6379` |
| `OPENSEARCH_PASSWORD` | Add a strong installation-specific value required by the production Compose definition |
| `LICENSE_SECRET_KEY` | Preserve the value recovered from `.env` or `casebender_secret` |
| `AUDIT_INTEGRITY_SECRET` | Preserve if present; otherwise generate once during managed preparation |
| Encryption and signing keys | Preserve existing values and legacy fallbacks |
| `NEXTAUTH_URL`, `NEXTAPP_URL` | Preserve the customer URLs |
| `DEPLOYMENT_PROFILE` | Set to `onprem` unless enterprise is licensed and prepared |
| `CASEBENDER_LEGACY_BOOTSTRAP` | Set to `false` |
| `ENTERPRISE_ALERT_PROMOTION` | Keep `disabled` until compatibility checks pass |
The release's `./casebender upgrade --version` or `--offline` archive path copies
`CASEBENDER_RELEASE_VERSION` and `CASEBENDER_REGISTRY` from the verified
`release.env`, and backfills missing audit and integration secrets. Never
replace an existing value during a routine migration.
Update `NO_PROXY` for the new internal names, including `postgres`, `redis`,
`web`, `api`, `worker`, and other enabled services.
## Phase 6: Rehearse the complete migration
Restore copies of PostgreSQL, attachments, `.env`, and secrets into an isolated
network. Use the same PostgreSQL major version as the source.
In rehearsal:
1. verify and extract the signed bundle;
2. preserve the intended Compose project name;
3. apply the `.env`, TLS, database-hostname, Redis, storage, and license changes;
4. run preflight;
5. start the pinned release;
6. verify migrations and service health;
7. compare baseline database and attachment counts;
8. validate login, cases, alerts, tasks, attachments, evidence, credentials,
integrations, audit writes, and backups;
9. complete the alert-promotion backfill checks before enabling promotion;
10. record the actual recovery point and recovery time.
Do not connect the rehearsal environment to production integrations.
## Phase 7: Production cutover
1. Announce a maintenance window and stop inbound integrations and user writes.
2. Take fresh final PostgreSQL and attachment backups.
3. Preserve the legacy Compose file as `docker-compose.legacy.yml`.
4. Place the verified on-premises archive in this directory (or keep Cosign
available for a connected `--version` download). If this host still has a
CLI that does not accept `--version`, copy only `casebender` from the
verified bundle into this directory once. Do not copy `release.env` or
replace `.env` by hand.
5. Preserve `.env` and apply the reviewed transformation.
6. Install trusted TLS files at:
```text theme={null}
deploy/nginx/ssl/fullchain.pem
deploy/nginx/ssl/privkey.pem
```
7. Stop the legacy stack without deleting volumes:
```bash theme={null}
docker compose -f docker-compose.legacy.yml down
```
8. Run:
```bash theme={null}
./casebender preflight
./casebender upgrade --version 1.0.9
# air-gapped:
# ./casebender upgrade --offline ./casebender-onprem-vX.Y.Z.tar.gz
./casebender logs
```
9. Keep `ENTERPRISE_ALERT_PROMOTION=disabled` until post-migration schema and
backfill verification passes. Then remove the override or set it to
`enabled`, recreate the caller services, and test a non-critical promotion.
## Phase 8: Validate and close the migration
Confirm:
* every expected container is healthy;
* the deployment remains `ACTIVE` and existing users can sign in;
* baseline users, organizations, cases, alerts, tasks, audit records, and
attachment counts match;
* representative attachments and evidence download correctly;
* stored integration credentials still decrypt and a safe connection test
succeeds;
* Redis, worker queues, and the alert-promotion outbox are healthy;
* updating a non-critical alert creates an audit entry without an integrity
error;
* creating and merging a non-critical alert into a case succeeds after
promotion is enabled;
* the deployment can produce a new backup.
Run the release canary:
```bash theme={null}
node scripts/deployment/canary-check.mjs \
https://casebender.your-company.example
```
Retain the legacy Compose file, previous image manifest, original `.env`,
database dump, object-store backup, and volume snapshots until the approved
rollback window closes.
## Rollback
Before starting the signed bundle, restart the legacy Compose file against the
untouched volumes if rehearsal or preparation fails.
After database migrations run:
* use `./casebender rollback --confirm-schema-compatible` only when the release
notes explicitly permit image-only rollback;
* otherwise stop the new stack, restore the matching pre-migration PostgreSQL
and attachment backups, restore the legacy `.env` and Compose file, and start
the previous pinned images.
Never run an older application image against an unsupported newer schema.
After this one-time migration succeeds, follow
[Upgrading CaseBender](/en/deployment/upgrading) for future releases.