Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"major": 1,
"minor": 8,
"patch": 20,
"patch": 21,
"prerelease": ""
}
9 changes: 7 additions & 2 deletions api-schema/tmi-openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "TMI (Threat Modeling Improved) API",
"description": "A RESTful API for collaborative threat modeling with full X6 graph library compatibility. This API provides schemas that align with AntV X6 cell object models for seamless integration with modern diagramming libraries. Supports OAuth 2.0 authentication with client callback integration for seamless single-page application authentication flows.\n\n## API Design v1.1.0\n\n### Authorization Model\nTMI uses hierarchical authorization: access control is defined at the ThreatModel level via the authorization field (readers, writers, owners). All child resources (Assets, Diagrams, Documents, Notes, Repositories, Threats) inherit permissions from their parent ThreatModel. This simplifies permission management and ensures consistent access control.\n\n### Bulk Operations\nNotes and Diagrams do not support bulk operations due to their unique creation workflows and lack of valid bulk use cases. All other resources (Threats, Assets, Documents, Repositories) support full bulk operations: POST (create), PUT (upsert), PATCH (partial update), DELETE (batch delete).\n\nAll resources support bulk metadata operations regardless of resource-level bulk support.\n\n### List Response Strategy\n- ThreatModels return summary information (TMListItem) because they contain many child objects that can be large.\n- Diagrams return summary information (DiagramListItem) because diagram data (cells, images) can be large.\n- Notes return summary information (NoteListItem) because the content field can be large.\n- Threats, Assets, Documents, Repositories return full schemas as they are relatively small and static.\n\n### PATCH Support\nAll resources support PATCH for partial updates using JSON Patch (RFC 6902). This is particularly useful for:\n- Assets: Array field updates (affected_assets, trust_boundaries) ensuring no duplicates\n- Notes: Updating name/description without changing content field\n- All resources: Efficient updates without full object replacement\n",
"version": "1.8.20",
"version": "1.8.21",
"contact": {
"name": "TMI Development Team",
"url": "https://github.com/ericfitz/tmi",
Expand Down Expand Up @@ -4521,7 +4521,12 @@
"attempts": 1,
"created_at": "2024-01-20T15:45:30Z",
"delivered_at": "2024-01-20T15:45:31Z",
"payload": {},
"payload": {
"type": "test",
"subscription_id": "11111111-1111-4111-8111-111111111111",
"timestamp": "2026-01-01T00:00:00Z",
"message": "This is a test webhook delivery"
},
"addon_id": "00000000-0000-0000-0000-000000000000",
"invoked_by": {
"principal_type": "user",
Expand Down
2,753 changes: 1,377 additions & 1,376 deletions api/api.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion api/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var (
// Minor version number
VersionMinor = "8"
// Patch version number
VersionPatch = "20"
VersionPatch = "21"
// VersionPreRelease is the pre-release label (e.g., "rc.0", "beta.1"), empty for stable releases
VersionPreRelease = ""
// GitCommit is the git commit hash from build
Expand Down
27 changes: 21 additions & 6 deletions cmd/dbtool/reference.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func writeJSONReference(path string, refs RefMap, serverURL, user, provider stri
return os.WriteFile(path, data, 0o600)
}

// SEM@d958f3dc26a0977ee70f472999b9749af2b714d3: serialize seeded resource IDs to a CATS-compatible YAML parameter substitution file (mutates shared state)
// SEM@0000000000000000000000000000000000000000: serialize seeded resource IDs to a CATS-compatible YAML parameter substitution file (mutates shared state)
func writeYAMLReference(path string, refs RefMap, user, provider string) error {
if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil {
return fmt.Errorf("failed to create output directory: %w", err)
Expand Down Expand Up @@ -214,6 +214,14 @@ func writeYAMLReference(path string, refs RefMap, user, provider string) error {
findRefByName(refs, teamNoteRef(realTeamName, 1), "")},
{"/admin/webhooks/subscriptions/{webhook_id}", "webhook_id",
findRefByName(refs, webhookRef(throwawayWebhookName), "")},
// Not a DELETE decoy: POST .../test on an operator-pinned subscription
// is refused with 403 (deliberate, unit-pinned behavior), and the
// global webhook_id IS the pinned subscription — so the /test
// endpoint's real logic never got fuzzed (39 guard-403s in run
// 20260820T034449Z). Point just this path at a non-pinned subscription;
// /test has no destructive operations, so it needs no protection.
{"/admin/webhooks/subscriptions/{webhook_id}/test", "webhook_id",
findRefByName(refs, webhookRef(testEndpointWebhookName), "")},
}
decoySections := ""
for _, d := range decoys {
Expand Down Expand Up @@ -560,11 +568,18 @@ const (
throwawayGroupName = "CATS Throwaway Group"
throwawayThreatModelName = "CATS Throwaway Threat Model"
throwawayWebhookName = "CATS Throwaway Webhook"
realTeamName = "CATS Test Team"
realWebhookName = "CATS Test Webhook"
realProjectName = "CATS Test Project"
realGroupName = "CATS Test Group"
realThreatModelName = "CATS Test Threat Model"
// Non-pinned subscription for the .../test endpoint override below: the
// real subscription is operator-pinned (which is what protects it from
// fuzz mutation), but POST .../{webhook_id}/test refuses pinned
// subscriptions with a 403, so pointing /test at the pinned one left the
// endpoint's actual logic entirely unfuzzed (39 guard-403s in run
// 20260820T034449Z).
testEndpointWebhookName = "CATS Test-Endpoint Webhook"
realTeamName = "CATS Test Team"
realWebhookName = "CATS Test Webhook"
realProjectName = "CATS Test Project"
realGroupName = "CATS Test Group"
realThreatModelName = "CATS Test Threat Model"
)

// findRefByName returns a seeded id by its exact seed ref, falling back to the
Expand Down
Loading
Loading