Bring Your Own Requirements
Product Security Hub ships with a comprehensive pre-built threat and requirement catalog, but every product is different. This guide shows you how to add your own custom threats and requirements — and how to bulk-update existing ones — using file imports or the REST API.
Before You Begin
- You have created a product in Product Security Hub
- You have added components to your architecture (custom threats and requirements are attached to components)
- You have downloaded the relevant import template from within PSH (go to Threats or Requirements → Import → Download Template)
How the import review process works
All file imports in Product Security Hub — whether you use the UI uploader or the REST API — follow the same staged review process. Understanding this flow before you start will save you confusion later.
🔑 Nothing is written directly to your product until you approve it
When you submit an import file, it is queued for a background processing job that runs approximately every 5 minutes. Once processed, the import is loaded into a staging environment and you receive an in-app notification. From the review screen you can inspect every proposed change, then either Approve it (writes to your production file) or Abandon it (discards all changes). Nothing reaches your product until a team member explicitly approves it.
Submit file
Upload via UI or POST to the API endpoint
Background job
Processed within ~5 minutes; staged for review
Review
You're notified; inspect every proposed change
Approve or Abandon
Approve writes to production; Abandon discards all
Note: The CycloneDX SBOM component import is the one exception — it loads directly so a scan can run immediately.
Choosing your approach
There are three ways to bring your own threats and requirements into PSH. Choose the one that fits what you're trying to do.
Add a single custom requirement in the UI
Best for one-off requirements. Navigate to Requirements → + Add Requirement and fill in the form. The requirement is linked directly to a component and threat of your choice.
Import new threats and requirements together ← most common
Best for adding a batch of custom threats with their associated requirements. Uses a combined import file where each row represents one requirement — so a single threat with four requirements produces four rows in the spreadsheet, one per requirement. This is the only path that creates new threats.
Update existing threats or requirements from a file
Best for bulk edits — update applicability, status, scoring justifications, narratives, and more across many records at once. Threats and requirements can be updated independently of each other using separate import files; you don't need to touch both at once.
Importing new threats and requirements together
The combined threats-and-requirements import is the only endpoint that creates new threats. Use it when you have custom threats that don't exist in the PSH catalog, each with one or more requirements linked to them.
Download the combined import template
Inside your product, navigate to Threats (or Requirements) → Import → Download Template. Always start from this template — it contains the exact column headers required and pre-populates with your current data so you never accidentally wipe a value.
Understand the file structure: one row per requirement
The combined import file is requirement-centric. Each row represents one requirement, and the threat information repeats across all rows that belong to the same threat. If you have one threat with four requirements, that's four rows — one for each requirement — all sharing the same threat columns.
Example: one threat (T-CUSTOM-01) with four requirements
| Threat Name | Threat Description | Requirement | Status |
|---|---|---|---|
| Unauthorized access via API | Attacker exploits... | Authenticate all API calls | WIP |
| Unauthorized access via API | Attacker exploits... | Enforce rate limiting | Met |
| Unauthorized access via API | Attacker exploits... | Log all failed auth attempts | Not Met |
| Unauthorized access via API | Attacker exploits... | Rotate API keys on schedule | WIP |
The threat columns repeat on every row — PSH uses them to group the requirements under a single threat on import.
Upload the completed file
Navigate to Threats → Import → Upload File, or use the REST API endpoint. Both paths trigger the same background processing job.
curl -X POST \
-H "X-Api-Key: <YOUR_API_KEY>" \
-F "file=@custom_threats_requirements.csv;type=text/csv" \
"https://app.productsecurityhub.com/api/v1/Products/{productId}/threats-and-requirements/import" Wait for the notification, then review and approve
The background job runs approximately every 5 minutes. Once your file is processed you'll receive an in-app notification. Open the review screen, inspect the proposed threats and requirements, and choose Approve to write them to your product or Abandon to discard the import.
Updating existing threats or requirements from a file
Use this path when you want to bulk-edit records that already exist in your product — update applicability, status, CVSS scoring, assessment notes, or any other editable field across many records at once.
Threats and requirements are updated independently
You don't need to update both at the same time. Upload a threats-only file to update just your threat assessments, or upload a requirements-only file to bulk-update status, narratives, and testing notes — whichever you need.
Updating existing threats
The threats update import lets you edit applicability, threat status, PM-CVSS scoring, scoring justifications, assessment notes, and the threat addendum fields. Threat identity and catalog text are read-only on import.
curl -X POST \
-H "X-Api-Key: <YOUR_API_KEY>" \
-F "file=@threats_update.csv;type=text/csv" \
"https://app.productsecurityhub.com/api/v1/Products/{productId}/threats/import" Match key: Unique Id (= publicUniqueId)
Updating existing requirements
The requirements update import lets you edit applicability, status (N/A | WIP | Met | Not Met), how the requirement will be met, testing notes, status notes, V&V IDs, and framework addendum fields. Marking a requirement Not Met automatically triggers generation of the associated residual risk.
Blank cells overwrite editable text fields
An empty HowWillThisBeMet, TestingNotes, or StatusNotes cell erases the existing value — even if you only intended to change the status. Always start from the pre-populated template so current values are already present.
curl -X POST \
-H "X-Api-Key: <YOUR_API_KEY>" \
-F "file=@requirements_update.csv;type=text/csv" \
"https://app.productsecurityhub.com/api/v1/Products/{productId}/requirements/import" Match key: Unique Id (= publicUniqueId). A requirement instance is scoped to a (component, threat) pair — the same requirement ID can appear on multiple components.
All of this works via the REST API too
Every import option on this page — creating new threats and requirements or updating existing ones — can be triggered through the PSH REST API using the same endpoints shown in the curl examples above. The API import triggers the same background processing job and the same staged review flow as the UI uploader, so the approval step is always required regardless of how you submit the file.
View the REST API ReferenceWhat can be edited on import
For catalog objects, identity and catalog text are read-only on import. Only assessment and narrative fields can be changed.
Threats — editable fields
- ✓ Applicability
- ✓ Threat status
- ✓ PM-CVSS vector metrics & scoring justification
- ✓ Threat addendum and notes
- ✗ Threat name, description, STRIDE category (read-only)
Requirements — editable fields
- ✓ Applicable
- ✓ Status (N/A | WIP | Met | Not Met)
- ✓ How Will This Be Met, Testing Notes, Status Notes
- ✓ V&V ID and framework addendum fields
- ✓ Security requirement text (custom requirements only)
- ✗ Identity fields — ThreatId, RequirementId, ComponentId (read-only)
Next steps
Once your custom requirements are approved, review residual risks for any requirements marked Not Met, or head to the REST API reference to automate the workflow.