mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2026-02-20 20:15:27 +01:00
Release catalyst
This commit is contained in:
160
definition/CAQLLexer.g4
Normal file
160
definition/CAQLLexer.g4
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 by Martin Mirchev
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Project : sqlite-parser; an ANTLR4 grammar for SQLite https://github.com/bkiers/sqlite-parser
|
||||
* Developed by : Bart Kiers, bart@big-o.nl
|
||||
*/
|
||||
|
||||
// $antlr-format alignTrailingComments on, columnLimit 150, maxEmptyLinesToKeep 1, reflowComments off, useTab off
|
||||
// $antlr-format allowShortRulesOnASingleLine on, alignSemicolons ownLine
|
||||
|
||||
lexer grammar CAQLLexer;
|
||||
|
||||
channels { ERRORCHANNEL }
|
||||
|
||||
|
||||
DOT: '.';
|
||||
|
||||
// https://github.com/arangodb/arangodb/blob/devel/arangod/Aql/grammar.y
|
||||
T_REGEX_MATCH: '=~'; // "~= operator"
|
||||
T_REGEX_NON_MATCH: '!~'; // "~! operator"
|
||||
|
||||
T_EQ: '=='; // "== operator";
|
||||
T_NE: '!='; // "!= operator";
|
||||
T_LT: '<'; // "< operator";
|
||||
T_GT: '>'; // "> operator";
|
||||
T_LE: '<='; // "<= operator";
|
||||
T_GE: '>='; // ">= operator";
|
||||
|
||||
T_PLUS: '+'; // "+ operator"
|
||||
T_MINUS: '-'; // "- operator"
|
||||
T_TIMES: '*'; // "* operator"
|
||||
T_DIV: '/'; // "/ operator"
|
||||
T_MOD: '%'; // "% operator"
|
||||
|
||||
T_QUESTION: '?'; // "?"
|
||||
T_COLON: ':'; // ":"
|
||||
T_SCOPE: '::'; // "::"
|
||||
T_RANGE: '..'; // ".."
|
||||
|
||||
T_COMMA: ','; // ","
|
||||
T_OPEN: '('; // "("
|
||||
T_CLOSE: ')'; // ")"
|
||||
T_OBJECT_OPEN: '{'; // "{"
|
||||
T_OBJECT_CLOSE: '}'; // "}"
|
||||
T_ARRAY_OPEN: '['; // "["
|
||||
T_ARRAY_CLOSE: ']'; // "]"
|
||||
|
||||
|
||||
// https://www.arangodb.com/docs/stable/aql/fundamentals-syntax.html#keywords
|
||||
T_AGGREGATE: A G G R E G A T E;
|
||||
T_ALL: A L L;
|
||||
T_AND: (A N D | '&&');
|
||||
T_ANY: A N Y;
|
||||
T_ASC: A S C;
|
||||
T_COLLECT: C O L L E C T;
|
||||
T_DESC: D E S C;
|
||||
T_DISTINCT: D I S T I N C T;
|
||||
T_FALSE: F A L S E;
|
||||
T_FILTER: F I L T E R;
|
||||
T_FOR: F O R;
|
||||
T_GRAPH: G R A P H;
|
||||
T_IN: I N;
|
||||
T_INBOUND: I N B O U N D;
|
||||
T_INSERT: I N S E R T;
|
||||
T_INTO: I N T O;
|
||||
T_K_SHORTEST_PATHS: K '_' S H O R T E S T '_' P A T H S;
|
||||
T_LET: L E T;
|
||||
T_LIKE: L I K E;
|
||||
T_LIMIT: L I M I T;
|
||||
T_NONE: N O N E;
|
||||
T_NOT: (N O T | '!');
|
||||
T_NULL: N U L L;
|
||||
T_OR: (O R | '||');
|
||||
T_OUTBOUND: O U T B O U N D;
|
||||
T_REMOVE: R E M O V E;
|
||||
T_REPLACE: R E P L A C E;
|
||||
T_RETURN: R E T U R N;
|
||||
T_SHORTEST_PATH: S H O R T E S T '_' P A T H;
|
||||
T_SORT: S O R T;
|
||||
T_TRUE: T R U E;
|
||||
T_UPDATE: U P D A T E;
|
||||
T_UPSERT: U P S E R T;
|
||||
T_WITH: W I T H;
|
||||
|
||||
T_KEEP: K E E P;
|
||||
T_COUNT: C O U N T;
|
||||
T_OPTIONS: O P T I O N S;
|
||||
T_PRUNE: P R U N E;
|
||||
T_SEARCH: S E A R C H;
|
||||
T_TO: T O;
|
||||
|
||||
T_CURRENT: C U R R E N T;
|
||||
T_NEW: N E W;
|
||||
T_OLD: O L D;
|
||||
|
||||
T_STRING: [a-zA-Z_] [a-zA-Z_0-9]*;
|
||||
|
||||
T_INT: [1-9] DIGIT* | '0' | '0x' HEX_DIGIT+ | '0b' [0-1]+;
|
||||
T_FLOAT: ( [1-9] DIGIT* | '0' )? '.' DIGIT+ (E [-+]? DIGIT+)?;
|
||||
|
||||
T_PARAMETER: '@' T_STRING;
|
||||
|
||||
T_QUOTED_STRING: ('\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\'' | '"' ( '\\'. | '""' | ~('"'| '\\') )* '"');
|
||||
|
||||
SINGLE_LINE_COMMENT: '//' ~[\r\n]* (('\r'? '\n') | EOF) -> channel(HIDDEN);
|
||||
|
||||
MULTILINE_COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
|
||||
|
||||
SPACES: [ \u000B\t\r\n] -> channel(HIDDEN);
|
||||
|
||||
UNEXPECTED_CHAR: .;
|
||||
|
||||
fragment HEX_DIGIT: [0-9a-fA-F];
|
||||
fragment DIGIT: [0-9];
|
||||
|
||||
fragment A: [aA];
|
||||
fragment B: [bB];
|
||||
fragment C: [cC];
|
||||
fragment D: [dD];
|
||||
fragment E: [eE];
|
||||
fragment F: [fF];
|
||||
fragment G: [gG];
|
||||
fragment H: [hH];
|
||||
fragment I: [iI];
|
||||
fragment J: [jJ];
|
||||
fragment K: [kK];
|
||||
fragment L: [lL];
|
||||
fragment M: [mM];
|
||||
fragment N: [nN];
|
||||
fragment O: [oO];
|
||||
fragment P: [pP];
|
||||
fragment Q: [qQ];
|
||||
fragment R: [rR];
|
||||
fragment S: [sS];
|
||||
fragment T: [tT];
|
||||
fragment U: [uU];
|
||||
fragment V: [vV];
|
||||
fragment W: [wW];
|
||||
fragment X: [xX];
|
||||
fragment Y: [yY];
|
||||
fragment Z: [zZ];
|
||||
|
||||
ERROR_RECONGNIGION: . -> channel(ERRORCHANNEL);
|
||||
109
definition/CAQLParser.g4
Normal file
109
definition/CAQLParser.g4
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 by Bart Kiers
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or
|
||||
* substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
||||
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Project : sqlite-parser; an ANTLR4 grammar for SQLite https://github.com/bkiers/sqlite-parser
|
||||
* Developed by:
|
||||
* Bart Kiers, bart@big-o.nl
|
||||
* Martin Mirchev, marti_2203@abv.bg
|
||||
* Mike Lische, mike@lischke-online.de
|
||||
*/
|
||||
|
||||
// $antlr-format alignTrailingComments on, columnLimit 130, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments off
|
||||
// $antlr-format useTab off, allowShortRulesOnASingleLine off, allowShortBlocksOnASingleLine on, alignSemicolons ownLine
|
||||
|
||||
parser grammar CAQLParser;
|
||||
|
||||
options {
|
||||
tokenVocab = CAQLLexer;
|
||||
}
|
||||
|
||||
parse: expression EOF
|
||||
;
|
||||
|
||||
expression:
|
||||
value_literal
|
||||
| reference
|
||||
| operator_unary
|
||||
| expression (T_PLUS|T_MINUS) expression
|
||||
| expression (T_TIMES|T_DIV|T_MOD) expression
|
||||
| expression T_RANGE expression
|
||||
| expression (T_LT|T_GT|T_LE|T_GE) expression
|
||||
| expression T_NOT? T_IN expression
|
||||
| expression (T_EQ|T_NE) expression
|
||||
| expression (T_ALL|T_ANY|T_NONE) eq_op=(T_EQ|T_NE|T_LT|T_GT|T_LE|T_GE|T_IN) expression
|
||||
| expression (T_ALL|T_ANY|T_NONE) T_NOT T_IN expression
|
||||
| expression T_NOT? (T_LIKE|T_REGEX_MATCH|T_REGEX_NON_MATCH) expression
|
||||
| expression T_AND expression
|
||||
| expression T_OR expression
|
||||
| expression T_QUESTION expression T_COLON expression
|
||||
| expression T_QUESTION T_COLON expression
|
||||
;
|
||||
|
||||
operator_unary: (
|
||||
T_PLUS expression
|
||||
| T_MINUS expression
|
||||
| T_NOT expression
|
||||
);
|
||||
|
||||
reference:
|
||||
T_STRING
|
||||
| compound_value
|
||||
| function_call
|
||||
| T_OPEN expression T_CLOSE
|
||||
| reference DOT T_STRING
|
||||
| reference T_ARRAY_OPEN expression T_ARRAY_CLOSE
|
||||
;
|
||||
|
||||
compound_value: (
|
||||
array
|
||||
| object
|
||||
);
|
||||
|
||||
function_call: (
|
||||
T_STRING T_OPEN expression? (T_COMMA expression)*? T_COMMA? T_CLOSE
|
||||
);
|
||||
|
||||
value_literal: (
|
||||
T_QUOTED_STRING
|
||||
| T_INT
|
||||
| T_FLOAT
|
||||
| T_NULL
|
||||
| T_TRUE
|
||||
| T_FALSE
|
||||
);
|
||||
|
||||
array:(
|
||||
T_ARRAY_OPEN expression? (T_COMMA expression)*? T_COMMA? T_ARRAY_CLOSE
|
||||
);
|
||||
|
||||
object:
|
||||
T_OBJECT_OPEN object_element? (T_COMMA object_element)* T_COMMA? T_OBJECT_CLOSE
|
||||
;
|
||||
|
||||
object_element:(
|
||||
T_STRING
|
||||
| object_element_name T_COLON expression
|
||||
| T_ARRAY_OPEN expression T_ARRAY_CLOSE T_COLON expression
|
||||
);
|
||||
|
||||
object_element_name:(
|
||||
T_STRING
|
||||
| T_QUOTED_STRING
|
||||
);
|
||||
29
definition/artifacts.yaml
Normal file
29
definition/artifacts.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths: { }
|
||||
|
||||
definitions:
|
||||
Artifact:
|
||||
type: object
|
||||
required: [ name ]
|
||||
properties:
|
||||
name: { type: string, example: "2.2.2.2" }
|
||||
type: { type: string }
|
||||
status: { type: string, example: "Unknown" }
|
||||
enrichments: { type: object, additionalProperties: { $ref: "#/definitions/Enrichment" } }
|
||||
|
||||
EnrichmentForm:
|
||||
type: object
|
||||
required: [ name, data ]
|
||||
properties:
|
||||
name: { type: string, example: "hash.sha1" }
|
||||
data: { type: object, example: { "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" } }
|
||||
|
||||
Enrichment:
|
||||
type: object
|
||||
required: [ name, data, created ]
|
||||
properties:
|
||||
name: { type: string, example: "hash.sha1" }
|
||||
data: { type: object, example: { "hash": "b7a067a742c20d07a7456646de89bc2d408a1153" } }
|
||||
created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
165
definition/automation.yaml
Normal file
165
definition/automation.yaml
Normal file
@@ -0,0 +1,165 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/automations:
|
||||
get:
|
||||
tags: [ "automations" ]
|
||||
summary: "List automations"
|
||||
operationId: "listAutomations"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/AutomationResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- id: comment
|
||||
image: "docker.io/python:3"
|
||||
script: ""
|
||||
type: [ playbook ]
|
||||
- id: hash.sha1
|
||||
image: "docker.io/python:3"
|
||||
script: ""
|
||||
type: [ global, artifact, playbook ]
|
||||
schema: "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}"
|
||||
- id: thehive
|
||||
image: "docker.io/python:3"
|
||||
script: ""
|
||||
type: [ global ]
|
||||
schema: "{\"title\":\"TheHive credentials\",\"type\":\"object\",\"properties\":{\"thehiveurl\":{\"type\":\"string\",\"title\":\"TheHive URL (e.g. 'https://thehive.example.org')\"},\"thehivekey\":{\"type\":\"string\",\"title\":\"TheHive API Key\"},\"skip_files\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Skip Files (much faster)\"},\"keep_ids\":{\"type\":\"boolean\", \"default\": true, \"title\":\"Keep IDs and overwrite existing IDs\"}},\"required\":[\"thehiveurl\", \"thehivekey\", \"skip_files\", \"keep_ids\"]}"
|
||||
- id: vt.hash
|
||||
image: "docker.io/python:3"
|
||||
script: ""
|
||||
type: [ global, artifact, playbook ]
|
||||
schema: "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}"
|
||||
security: [ { roles: [ "automation:read" ] } ]
|
||||
post:
|
||||
tags: [ "automations" ]
|
||||
summary: "Create a new automation"
|
||||
operationId: "createAutomation"
|
||||
parameters:
|
||||
- { name: "automation", in: "body", description: "New automation", required: true, schema: { $ref: "#/definitions/AutomationForm" }, x-example: { id: "hash-sha-256", image: "docker.io/python:3", script: "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))\n return {'hash': sha256.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", type: [ global ] } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/AutomationResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: "hash-sha-256"
|
||||
image: "docker.io/python:3"
|
||||
type: [ global ]
|
||||
script: |
|
||||
import sys
|
||||
import json
|
||||
import hashlib
|
||||
|
||||
|
||||
def run(msg):
|
||||
sha256 = hashlib.sha256(msg['payload']['default'].encode('utf-8'))
|
||||
return {'hash': sha256.hexdigest()}
|
||||
|
||||
|
||||
print(json.dumps(run(json.loads(sys.argv[1]))))
|
||||
|
||||
security: [ { roles: [ "automation:write" ] } ]
|
||||
|
||||
/automations/{id}:
|
||||
get:
|
||||
tags: [ "automations" ]
|
||||
summary: "Get a single automation"
|
||||
operationId: "getAutomation"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Automation ID", required: true, type: string, x-example: "hash.sha1" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/AutomationResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: hash.sha1
|
||||
image: "docker.io/python:3"
|
||||
type: [ global, artifact, playbook ]
|
||||
schema: "{\"title\":\"Input\",\"type\":\"object\",\"properties\":{\"default\":{\"type\":\"string\",\"title\":\"Value\"}},\"required\":[\"default\"]}"
|
||||
script: |
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import json
|
||||
import hashlib
|
||||
|
||||
|
||||
def run(msg):
|
||||
sha1 = hashlib.sha1(msg['payload']['default'].encode('utf-8'))
|
||||
return {"hash": sha1.hexdigest()}
|
||||
|
||||
|
||||
print(json.dumps(run(json.loads(sys.argv[1]))))
|
||||
security: [ { roles: [ "automation:read" ] } ]
|
||||
put:
|
||||
tags: [ "automations" ]
|
||||
summary: "Update an existing automation"
|
||||
operationId: "updateAutomation"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Automation ID", required: true, type: string, x-example: "hash.sha1" }
|
||||
- { name: "automation", in: "body", description: "Automation object that needs to be added", required: true, schema: { $ref: "#/definitions/AutomationForm" }, x-example: { id: hash.sha1, image: "docker.io/python:3", script: "import sys\nimport json\nimport hashlib\n\n\ndef run(msg):\n sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))\n return {'hash': sha1.hexdigest()}\n\n\nprint(json.dumps(run(json.loads(sys.argv[1]))))\n", type: [ global, artifact, playbook ] } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/AutomationResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: hash.sha1
|
||||
image: "docker.io/python:3"
|
||||
type: [ global, artifact, playbook ]
|
||||
script: |
|
||||
import sys
|
||||
import json
|
||||
import hashlib
|
||||
|
||||
|
||||
def run(msg):
|
||||
sha1 = hashlib.sha1(msg['payload'].encode('utf-8'))
|
||||
return {'hash': sha1.hexdigest()}
|
||||
|
||||
|
||||
print(json.dumps(run(json.loads(sys.argv[1]))))
|
||||
security: [ { roles: [ "automation:write" ] } ]
|
||||
delete:
|
||||
tags: [ "automations" ]
|
||||
summary: "Delete a automation"
|
||||
operationId: "deleteAutomation"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Automation ID", required: true, type: string, x-example: "hash.sha1" }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "automation:write" ] } ]
|
||||
|
||||
definitions:
|
||||
AutomationForm:
|
||||
type: object
|
||||
required: [ id, image, script, type ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
image: { type: string }
|
||||
script: { type: string }
|
||||
type: { type: array, items: { type: string, enum: [ artifact, playbook, global ] } }
|
||||
schema: { type: string, example: "{}" }
|
||||
|
||||
Automation:
|
||||
type: object
|
||||
required: [ image, script, type ]
|
||||
properties:
|
||||
image: { type: string }
|
||||
script: { type: string }
|
||||
type: { type: array, items: { type: string, enum: [ artifact, playbook, global ] } }
|
||||
schema: { type: string, example: "{}" }
|
||||
|
||||
AutomationResponse:
|
||||
type: object
|
||||
required: [ id, image, script, type ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
image: { type: string }
|
||||
script: { type: string }
|
||||
type: { type: array, items: { type: string, enum: [ artifact, playbook, global ] } }
|
||||
schema: { type: string, example: "{}" }
|
||||
52
definition/enterprise/graph.yaml
Normal file
52
definition/enterprise/graph.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/graph/{col}/{id}:
|
||||
get:
|
||||
tags: [ "graph" ]
|
||||
summary: "Graph"
|
||||
operationId: "graph"
|
||||
parameters:
|
||||
- { name: "col", in: "path", description: "Graph Start", required: true, type: string, x-example: "tickets" }
|
||||
- { name: "id", in: "path", description: "Graph Start", required: true, type: string, x-example: "88" }
|
||||
- { name: "depth", in: "query", description: "Graph Start", required: true, type: integer, x-example: 1 }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/Graph" }
|
||||
examples:
|
||||
test:
|
||||
nodes:
|
||||
- { id: "artifacts/94d5cab6f5fe3422a447ab15436e7a672bc0c09a", name: "94d5cab6f5fe3422a447ab15436e7a672bc0c09a" }
|
||||
- { id: "artifacts/http%3A%2F%2Fwww.customerviral.io%2Fscalable%2Fvertical%2Fkiller", name: "http://www.customerviral.io/scalable/vertical/killer" }
|
||||
- { id: "artifacts/leadreintermediate.io", name: "leadreintermediate.io" }
|
||||
- { id: "tickets/88", name: "live zebra" }
|
||||
links:
|
||||
- { id: "296239", sid: "tickets/88", tid: "artifacts/http%3A%2F%2Fwww.customerviral.io%2Fscalable%2Fvertical%2Fkiller" }
|
||||
- { id: "296240", sid: "tickets/88", tid: "artifacts/leadreintermediate.io" }
|
||||
- { id: "296242", sid: "tickets/88", tid: "artifacts/94d5cab6f5fe3422a447ab15436e7a672bc0c09a" }
|
||||
security: [ { roles: [ "ticket:read" ] } ]
|
||||
|
||||
definitions:
|
||||
Graph:
|
||||
type: object
|
||||
properties:
|
||||
nodes: { type: array, items: { $ref: "#/definitions/Node" } }
|
||||
links: { type: array, items: { $ref: "#/definitions/Link" } }
|
||||
|
||||
Node:
|
||||
type: object
|
||||
required: [ id, name ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
|
||||
Link:
|
||||
type: object
|
||||
required: [ id, tid, sid ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
# name: { type: string }
|
||||
tid: { type: string }
|
||||
sid: { type: string }
|
||||
84
definition/enterprise/groups.yaml
Normal file
84
definition/enterprise/groups.yaml
Normal file
@@ -0,0 +1,84 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/groups:
|
||||
get:
|
||||
tags: [ "groups" ]
|
||||
summary: "List groups"
|
||||
operationId: "listGroups"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/Group" } }
|
||||
security: [ { roles: [ "group:read" ] } ]
|
||||
post:
|
||||
tags: [ "groups" ]
|
||||
summary: "Create a new group"
|
||||
operationId: "createGroup"
|
||||
parameters:
|
||||
- { name: "group", in: "body", description: "New group", required: true, schema: { $ref: "#/definitions/GroupForm" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/GroupResponse" }
|
||||
security: [ { roles: [ "group:write" ] } ]
|
||||
|
||||
/groups/{id}:
|
||||
get:
|
||||
tags: [ "groups" ]
|
||||
summary: "Get a single group"
|
||||
operationId: "getGroup"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Group ID", required: true, type: string }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/GroupResponse" }
|
||||
security: [ { roles: [ "group:read" ] } ]
|
||||
put:
|
||||
tags: [ "groups" ]
|
||||
summary: "Update an existing group"
|
||||
operationId: "updateGroup"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Group ID", required: true, type: string }
|
||||
- { name: "group", in: "body", description: "Group object that needs to be added", required: true, schema: { $ref: "#/definitions/Group" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/Group" }
|
||||
security: [ { roles: [ "group:write" ] } ]
|
||||
delete:
|
||||
tags: [ "groups" ]
|
||||
summary: "Delete a group"
|
||||
operationId: "deleteGroup"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Group ID", required: true, type: string }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "group:write" ] } ]
|
||||
|
||||
definitions:
|
||||
GroupForm:
|
||||
type: object
|
||||
required: [ name, users ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
users: { type: array, items: { type: string } }
|
||||
|
||||
Group:
|
||||
type: object
|
||||
required: [ name, users ]
|
||||
properties:
|
||||
name: { type: string }
|
||||
users: { type: array, items: { type: string } }
|
||||
|
||||
|
||||
GroupResponse:
|
||||
type: object
|
||||
required: [ id, name, users ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
users: { type: array, items: { type: string } }
|
||||
110
definition/enterprise/rules.yaml
Normal file
110
definition/enterprise/rules.yaml
Normal file
@@ -0,0 +1,110 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/rules:
|
||||
get:
|
||||
tags: [ "rules" ]
|
||||
summary: "List rules"
|
||||
operationId: "listRules"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/RuleResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- id: ignore-alerts
|
||||
name: Ignore Alerts
|
||||
condition: "type == 'alert'"
|
||||
update: { "status": "closed" }
|
||||
security: [ { roles: [ "rule:read" ] } ]
|
||||
post:
|
||||
tags: [ "rules" ]
|
||||
summary: "Create a rule"
|
||||
operationId: "createRule"
|
||||
parameters:
|
||||
- { name: "rule", in: "body", description: "New rule", required: true, schema: { $ref: "#/definitions/RuleForm" }, x-example: { name: "Ignore all Alerts", condition: "type == 'alert'", update: { "status": "closed" } } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/RuleResponse" } }
|
||||
examples:
|
||||
test:
|
||||
id: ignore-all-alerts
|
||||
name: Ignore all Alerts
|
||||
condition: "type == 'alert'"
|
||||
update: { "status": "closed" }
|
||||
security: [ { roles: [ "rule:write" ] } ]
|
||||
|
||||
/rules/{id}:
|
||||
get:
|
||||
tags: [ "rules" ]
|
||||
summary: "Get a single rule"
|
||||
operationId: "getRule"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Rule name", required: true, type: string, x-example: "ignore-alerts" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/RuleResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: ignore-alerts
|
||||
name: Ignore Alerts
|
||||
condition: "type == 'alert'"
|
||||
update: { "status": "closed" }
|
||||
security: [ { roles: [ "rule:read" ] } ]
|
||||
put:
|
||||
tags: [ "rules" ]
|
||||
summary: "Update an existing ticket rule"
|
||||
operationId: "updateRule"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Rule ID", required: true, type: string, x-example: "ignore-alerts" }
|
||||
- { name: "rule", in: "body", description: "Updated rule", required: true, schema: { $ref: "#/definitions/RuleForm" }, x-example: { name: "Ignore Alerts", condition: "type == 'alert'", update: { "status": "invalid" } } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/RuleResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: ignore-alerts
|
||||
name: Ignore Alerts
|
||||
condition: "type == 'alert'"
|
||||
update: { "status": "invalid" }
|
||||
security: [ { roles: [ "rule:write" ] } ]
|
||||
delete:
|
||||
tags: [ "rules" ]
|
||||
summary: "Delete a rule"
|
||||
operationId: "deleteRule"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Rule name", required: true, type: string, x-example: "ignore-alerts" }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "rule:write" ] } ]
|
||||
|
||||
definitions:
|
||||
RuleForm:
|
||||
type: object
|
||||
required: [ name, condition, update ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
condition: { type: string }
|
||||
update: { type: object }
|
||||
|
||||
Rule:
|
||||
type: object
|
||||
required: [ name, condition, update ]
|
||||
properties:
|
||||
name: { type: string }
|
||||
condition: { type: string }
|
||||
update: { type: object }
|
||||
|
||||
RuleResponse:
|
||||
type: object
|
||||
required: [ id, name, condition, update ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
condition: { type: string }
|
||||
update: { type: object }
|
||||
130
definition/jobs.yaml
Normal file
130
definition/jobs.yaml
Normal file
@@ -0,0 +1,130 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/jobs:
|
||||
get:
|
||||
tags: [ "jobs" ]
|
||||
summary: "List jobs"
|
||||
operationId: "listJobs"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/JobResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- id: "99cd67131b48"
|
||||
automation: "hash.sha1"
|
||||
payload: "test"
|
||||
status: "created"
|
||||
security: [ { roles: [ "job:read" ] } ]
|
||||
post:
|
||||
tags: [ "jobs" ]
|
||||
summary: "Start a new job"
|
||||
operationId: "runJob"
|
||||
parameters:
|
||||
- { name: "job", in: "body", description: "New job", required: true, schema: { $ref: "#/definitions/JobForm" }, x-example: { automation: "hash.sha1", message: { payload: "test" } } }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "job:write" ] } ]
|
||||
|
||||
/jobs/{id}:
|
||||
get:
|
||||
tags: [ "jobs" ]
|
||||
summary: "Get a single job"
|
||||
operationId: "getJob"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Job ID", required: true, type: string, x-example: "99cd67131b48" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/JobResponse" }
|
||||
examples:
|
||||
test: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "created" }
|
||||
security: [ { roles: [ "job:read" ] } ]
|
||||
put:
|
||||
tags: [ "jobs" ]
|
||||
summary: "Update an existing job"
|
||||
operationId: "updateJob"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Job ID", required: true, type: string, x-example: "99cd67131b48" }
|
||||
- { name: "job", in: "body", description: "Job object that needs to be added", required: true, schema: { $ref: "#/definitions/Job" }, x-example: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "failed" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/JobResponse" }
|
||||
examples:
|
||||
test: { id: "99cd67131b48", automation: "hash.sha1", payload: "test", status: "failed" }
|
||||
|
||||
security: [ { roles: [ "job:write" ] } ]
|
||||
|
||||
definitions:
|
||||
Message:
|
||||
type: object
|
||||
properties:
|
||||
payload: { type: object }
|
||||
secrets: { type: object, additionalProperties: { type: string } }
|
||||
context: { $ref: "#/definitions/Context" }
|
||||
|
||||
Context:
|
||||
type: object
|
||||
properties:
|
||||
artifact: { $ref: "#/definitions/Artifact" }
|
||||
playbook: { $ref: "#/definitions/PlaybookResponse" }
|
||||
task: { $ref: "#/definitions/TaskResponse" }
|
||||
ticket: { $ref: "#/definitions/TicketResponse" }
|
||||
|
||||
Origin:
|
||||
type: object
|
||||
properties:
|
||||
task_origin: { $ref: "#/definitions/TaskOrigin" }
|
||||
artifact_origin: { $ref: "#/definitions/ArtifactOrigin" }
|
||||
|
||||
TaskOrigin:
|
||||
type: object
|
||||
required: [ ticket_id, playbook_id, task_id ]
|
||||
properties:
|
||||
ticket_id: { type: integer, format: int64 }
|
||||
playbook_id: { type: string }
|
||||
task_id: { type: string }
|
||||
|
||||
ArtifactOrigin:
|
||||
type: object
|
||||
required: [ ticket_id, artifact ]
|
||||
properties:
|
||||
ticket_id: { type: integer, format: int64 }
|
||||
artifact: { type: string }
|
||||
|
||||
JobForm:
|
||||
type: object
|
||||
required: [ automation ]
|
||||
properties:
|
||||
automation: { type: string }
|
||||
payload: { }
|
||||
origin: { $ref: "#/definitions/Origin" }
|
||||
|
||||
Job:
|
||||
type: object
|
||||
required: [ automation, running, status ]
|
||||
properties:
|
||||
automation: { type: string }
|
||||
container: { type: string }
|
||||
payload: { }
|
||||
running: { type: boolean }
|
||||
status: { type: string }
|
||||
log: { type: string }
|
||||
output: { type: object }
|
||||
origin: { $ref: "#/definitions/Origin" }
|
||||
|
||||
JobResponse:
|
||||
type: object
|
||||
required: [ id, automation, status ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
automation: { type: string }
|
||||
container: { type: string }
|
||||
status: { type: string }
|
||||
payload: { }
|
||||
log: { type: string }
|
||||
output: { type: object }
|
||||
origin: { $ref: "#/definitions/Origin" }
|
||||
30
definition/logs.yaml
Normal file
30
definition/logs.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
|
||||
/logs/{reference}:
|
||||
get:
|
||||
tags: [ "logs" ]
|
||||
summary: "Get log entries"
|
||||
operationId: "getLogs"
|
||||
parameters:
|
||||
- { name: "reference", in: "path", description: "Reference", required: true, type: string, x-example: "tickets%2F294511" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/LogEntry" } }
|
||||
examples:
|
||||
test:
|
||||
- { "created": "2021-10-02T18:05:00.333535+02:00","creator": "bob","reference": "tickets/294511","message": "Fail run account resist lend solve incident centre priority temperature. Cause change distribution examine location technique shape partner milk customer. Rail tea plate soil report cook railway interpretation breath action. Exercise dream accept park conclusion addition shoot assistance may answer. Gold writer link stop combine hear power name commitment operation. Determine lifespan support grow degree henry exclude detail set religion. Direct library policy convention chain retain discover ride walk student. Gather proposal select march aspect play noise avoid encourage employ. Assessment preserve transport combine wish influence income guess run stand. Charge limit crime ignore statement foundation study issue stop claim." }
|
||||
security: [ { roles: [ "log:read" ] } ]
|
||||
|
||||
definitions:
|
||||
LogEntry:
|
||||
type: object
|
||||
required: [ reference, creator, created, message ]
|
||||
properties:
|
||||
reference: { type: string }
|
||||
creator: { type: string }
|
||||
created: { type: string, format: "date-time" }
|
||||
message: { type: string }
|
||||
202
definition/playbooks.yaml
Normal file
202
definition/playbooks.yaml
Normal file
@@ -0,0 +1,202 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/playbooks:
|
||||
get:
|
||||
tags: [ "playbooks" ]
|
||||
summary: "List playbooks"
|
||||
operationId: "listPlaybooks"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/PlaybookTemplateResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- id: malware
|
||||
name: Malware
|
||||
yaml: "name: Malware\ntasks:\n file-or-hash:\n name: Do you have the file or the hash?\n type: input\n schema:\n title: Malware\n type: object\n properties:\n file:\n type: string\n title: \"I have the\"\n enum: [ \"File\", \"Hash\" ]\n next:\n enter-hash: \"file == 'Hash'\"\n upload: \"file == 'File'\"\n\n enter-hash:\n name: Please enter the hash\n type: input\n schema:\n title: Malware\n type: object\n properties:\n hash:\n type: string\n title: Please enter the hash value\n minlength: 32\n next:\n virustotal: \"hash != ''\"\n\n upload:\n name: Upload the malware\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: object\n x-display: file\n title: Please upload the malware\n next:\n hash: \"malware\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['upload'].data['malware']\"\n next:\n virustotal:\n\n virustotal:\n name: Send hash to VirusTotal\n type: automation\n automation: vt.hash\n args:\n hash: \"playbook.tasks['enter-hash'].data['hash'] || playbook.tasks['hash'].data['hash']\"\n # next:\n # known-malware: \"score > 5\"\n # sandbox: \"score < 6\" # unknown-malware\n"
|
||||
- id: phishing
|
||||
name: Phishing
|
||||
yaml: "name: Phishing\ntasks:\n board:\n name: Board Involvement?\n description: Is a board member involved?\n type: input\n schema:\n properties:\n boardInvolved:\n default: false\n title: A board member is involved.\n type: boolean\n required:\n - boardInvolved\n title: Board Involvement?\n type: object\n next:\n escalate: \"boardInvolved == true\"\n mail-available: \"boardInvolved == false\"\n\n escalate:\n name: Escalate to CISO\n description: Please escalate the task to the CISO\n type: task\n\n mail-available:\n name: Mail available\n type: input\n schema:\n oneOf:\n - properties:\n mail:\n title: Mail\n type: string\n x-display: textarea\n schemaKey:\n const: 'yes'\n type: string\n required:\n - mail\n title: 'Yes'\n - properties:\n schemaKey:\n const: 'no'\n type: string\n title: 'No'\n title: Mail available\n type: object\n next:\n block-sender: \"schemaKey == 'yes'\"\n extract-iocs: \"schemaKey == 'yes'\"\n search-email-gateway: \"schemaKey == 'no'\"\n\n search-email-gateway:\n name: Search email gateway\n description: Please search email-gateway for the phishing mail.\n type: task\n next:\n extract-iocs:\n\n block-sender:\n name: Block sender\n type: task\n next:\n extract-iocs:\n\n extract-iocs:\n name: Extract IOCs\n description: Please insert the IOCs\n type: input\n schema:\n properties:\n iocs:\n items:\n type: string\n title: IOCs\n type: array\n title: Extract IOCs\n type: object\n next:\n block-iocs:\n\n block-iocs:\n name: Block IOCs\n type: task\n"
|
||||
- id: simple
|
||||
name: Simple
|
||||
yaml: "name: Simple\ntasks:\n input:\n name: Enter something to hash\n type: input\n schema:\n title: Something\n type: object\n properties:\n something:\n type: string\n title: Something\n default: \"\"\n next:\n hash: \"something != ''\"\n\n hash:\n name: Hash the something\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['something']\"\n next:\n comment: \"hash != ''\"\n\n comment:\n name: Comment the hash\n type: automation\n automation: comment\n payload:\n default: \"playbook.tasks['hash'].data['hash']\"\n next:\n done: \"done\"\n\n done:\n name: You can close this case now\n type: task\n"
|
||||
security: [ { roles: [ "playbook:read" ] } ]
|
||||
post:
|
||||
tags: [ "playbooks" ]
|
||||
summary: "Create a playbook"
|
||||
operationId: "createPlaybook"
|
||||
parameters:
|
||||
- { name: "playbook", in: "body", description: "New playbook", required: true, schema: { $ref: "#/definitions/PlaybookTemplateForm" }, x-example: { yaml: "name: Simple2\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/PlaybookTemplateResponse" } }
|
||||
examples:
|
||||
test:
|
||||
id: simple-2
|
||||
name: Simple2
|
||||
yaml: |
|
||||
name: Simple2
|
||||
tasks:
|
||||
input:
|
||||
name: Upload malware if possible
|
||||
type: input
|
||||
schema:
|
||||
title: Malware
|
||||
type: object
|
||||
properties:
|
||||
malware:
|
||||
type: string
|
||||
title: Select malware
|
||||
default: ""
|
||||
next:
|
||||
hash: "malware != ''"
|
||||
|
||||
hash:
|
||||
name: Hash the malware
|
||||
type: automation
|
||||
automation: hash.sha1
|
||||
payload:
|
||||
default: "playbook.tasks['input'].data['malware']"
|
||||
next:
|
||||
escalate:
|
||||
|
||||
escalate:
|
||||
name: Escalate to malware team
|
||||
type: task
|
||||
security: [ { roles: [ "playbook:write" ] } ]
|
||||
|
||||
/playbooks/{id}:
|
||||
get:
|
||||
tags: [ "playbooks" ]
|
||||
summary: "Get a single playbook"
|
||||
operationId: "getPlaybook"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Playbook name", required: true, type: string, x-example: "simple" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/PlaybookTemplateResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: simple
|
||||
name: Simple
|
||||
yaml: |
|
||||
name: Simple
|
||||
tasks:
|
||||
input:
|
||||
name: Enter something to hash
|
||||
type: input
|
||||
schema:
|
||||
title: Something
|
||||
type: object
|
||||
properties:
|
||||
something:
|
||||
type: string
|
||||
title: Something
|
||||
default: ""
|
||||
next:
|
||||
hash: "something != ''"
|
||||
|
||||
hash:
|
||||
name: Hash the something
|
||||
type: automation
|
||||
automation: hash.sha1
|
||||
payload:
|
||||
default: "playbook.tasks['input'].data['something']"
|
||||
next:
|
||||
comment: "hash != ''"
|
||||
|
||||
comment:
|
||||
name: Comment the hash
|
||||
type: automation
|
||||
automation: comment
|
||||
payload:
|
||||
default: "playbook.tasks['hash'].data['hash']"
|
||||
next:
|
||||
done: "done"
|
||||
|
||||
done:
|
||||
name: You can close this case now
|
||||
type: task
|
||||
|
||||
security: [ { roles: [ "playbook:read" ] } ]
|
||||
put:
|
||||
tags: [ "playbooks" ]
|
||||
summary: "Update an existing ticket playbook"
|
||||
operationId: "updatePlaybook"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Playbook ID", required: true, type: string, x-example: "simple" }
|
||||
- { name: "playbook", in: "body", description: "Updated playbook", required: true, schema: { $ref: "#/definitions/PlaybookTemplateForm" }, x-example: { yaml: "name: Simple\ntasks:\n input:\n name: Upload malware if possible\n type: input\n schema:\n title: Malware\n type: object\n properties:\n malware:\n type: string\n title: Select malware\n default: \"\"\n next:\n hash: \"malware != ''\"\n\n hash:\n name: Hash the malware\n type: automation\n automation: hash.sha1\n payload:\n default: \"playbook.tasks['input'].data['malware']\"\n next:\n escalate:\n\n escalate:\n name: Escalate to malware team\n type: task\n" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/PlaybookTemplateResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: simple
|
||||
name: Simple
|
||||
yaml: |
|
||||
name: Simple
|
||||
tasks:
|
||||
input:
|
||||
name: Upload malware if possible
|
||||
type: input
|
||||
schema:
|
||||
title: Malware
|
||||
type: object
|
||||
properties:
|
||||
malware:
|
||||
type: string
|
||||
title: Select malware
|
||||
default: ""
|
||||
next:
|
||||
hash: "malware != ''"
|
||||
|
||||
hash:
|
||||
name: Hash the malware
|
||||
type: automation
|
||||
automation: hash.sha1
|
||||
payload:
|
||||
default: "playbook.tasks['input'].data['malware']"
|
||||
next:
|
||||
escalate:
|
||||
|
||||
escalate:
|
||||
name: Escalate to malware team
|
||||
type: task
|
||||
security: [ { roles: [ "playbook:write" ] } ]
|
||||
delete:
|
||||
tags: [ "playbooks" ]
|
||||
summary: "Delete a playbook"
|
||||
operationId: "deletePlaybook"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Playbook name", required: true, type: string, x-example: "simple" }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "playbook:write" ] } ]
|
||||
|
||||
definitions:
|
||||
PlaybookTemplateForm:
|
||||
type: object
|
||||
required: [ yaml ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
yaml: { type: string }
|
||||
|
||||
PlaybookTemplate:
|
||||
type: object
|
||||
required: [ name, yaml ]
|
||||
properties:
|
||||
name: { type: string }
|
||||
yaml: { type: string }
|
||||
|
||||
PlaybookTemplateResponse:
|
||||
type: object
|
||||
required: [ id, name, yaml ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
yaml: { type: string }
|
||||
59
definition/settings.yaml
Normal file
59
definition/settings.yaml
Normal file
@@ -0,0 +1,59 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/settings:
|
||||
get:
|
||||
tags: [ "settings" ]
|
||||
summary: "Get settings"
|
||||
operationId: "getSettings"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/Settings" }
|
||||
examples:
|
||||
test:
|
||||
version: "0.0.0-test"
|
||||
tier: community
|
||||
timeformat: "YYYY-MM-DDThh:mm:ss"
|
||||
ticketTypes:
|
||||
- { icon: "mdi-alert", id: "alert", name: "Alerts", default_template: "default", default_playbooks: [ ] }
|
||||
- { icon: "mdi-radioactive", id: "incident", name: "Incidents", default_template: "default", default_playbooks: [ ] }
|
||||
- { icon: "mdi-fingerprint", id: "investigation", name: "Forensic Investigations", default_template: "default", default_playbooks: [ ] }
|
||||
- { icon: "mdi-target", id: "hunt", name: "Threat Hunting", default_template: "default", default_playbooks: [ ] }
|
||||
artifactStates:
|
||||
- { icon: "mdi-help-circle-outline", id: "unknown", name: "Unknown", color: "info" }
|
||||
- { icon: "mdi-skull", id: "malicious", name: "Malicious", color: "error" }
|
||||
- { icon: "mdi-check", id: "clean", name: "Clean", color: "success" }
|
||||
roles: [
|
||||
"admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write",
|
||||
"admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read",
|
||||
"admin:userdata:write", "analyst:automation:read",
|
||||
"analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read",
|
||||
"analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read",
|
||||
"analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write",
|
||||
"analyst:tickettype:read", "analyst:user:read", "engineer:automation:write",
|
||||
"engineer:playbook:write", "engineer:rule:write", "engineer:template:write",
|
||||
"engineer:tickettype:write" ]
|
||||
security: [ { roles: [ "settings:read" ] } ]
|
||||
|
||||
definitions:
|
||||
Settings:
|
||||
type: object
|
||||
required: [ version, tier, timeformat, ticketTypes, artifactStates ]
|
||||
properties:
|
||||
version: { title: "Version", type: string }
|
||||
tier: { title: "Tier", type: string, enum: [ "community", "enterprise" ] }
|
||||
timeformat: { title: "Time Format", type: string }
|
||||
ticketTypes: { title: "Ticket Types", type: array, items: { $ref: "#/definitions/TicketTypeResponse" } }
|
||||
artifactStates: { title: "Artifact States", type: array, items: { $ref: "#/definitions/Type" } }
|
||||
roles: { title: "Roles", type: array, items: { type: string } }
|
||||
|
||||
Type:
|
||||
type: object
|
||||
required: [ id, name, icon ]
|
||||
properties:
|
||||
id: { title: ID, type: string, x-cols: 3, x-class: pr-2 }
|
||||
name: { title: Name, type: string, x-cols: 3, x-class: pr-2 }
|
||||
icon: { title: "Icon (https://materialdesignicons.com)", type: string, x-cols: 3, x-class: pr-2 }
|
||||
color: { title: Color, type: string, x-cols: 3, enum: [ error, info, success, warning ] }
|
||||
31
definition/statistics.yaml
Normal file
31
definition/statistics.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/statistics:
|
||||
get:
|
||||
tags: [ "statistics" ]
|
||||
summary: "Get statistics"
|
||||
operationId: "getStatistics"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: '#/definitions/Statistics' }
|
||||
examples:
|
||||
test:
|
||||
unassigned: 0
|
||||
open_tickets_per_user: { }
|
||||
tickets_per_week: { "2021-39": 3 }
|
||||
tickets_per_type: { "alert": 2, "incident": 1 }
|
||||
security: [ { roles: [ "ticket:read" ] } ]
|
||||
|
||||
definitions:
|
||||
|
||||
Statistics:
|
||||
type: object
|
||||
required: [ unassigned, open_tickets_per_user, tickets_per_week, tickets_per_type ]
|
||||
properties:
|
||||
unassigned: { type: integer }
|
||||
open_tickets_per_user: { type: object, additionalProperties: { type: integer } }
|
||||
tickets_per_week: { type: object, additionalProperties: { type: integer } }
|
||||
tickets_per_type: { type: object, additionalProperties: { type: integer } }
|
||||
18
definition/swagger.yaml
Normal file
18
definition/swagger.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
swagger: "2.0"
|
||||
info:
|
||||
version: "0.0.3"
|
||||
title: "Catalyst"
|
||||
description: API for the catalyst incident response platform.
|
||||
|
||||
host: "."
|
||||
basePath: "/api"
|
||||
schemes:
|
||||
# - "https"
|
||||
- "http"
|
||||
|
||||
consumes: [ "application/json" ]
|
||||
produces: [ "application/json" ]
|
||||
|
||||
paths: {}
|
||||
|
||||
definitions: {}
|
||||
107
definition/tasks.yaml
Normal file
107
definition/tasks.yaml
Normal file
@@ -0,0 +1,107 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/tasks:
|
||||
get:
|
||||
tags: [ "tasks" ]
|
||||
summary: "List tasks"
|
||||
operationId: "listTasks"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/TaskResponse" } }
|
||||
examples:
|
||||
test: [ ]
|
||||
security: [ { roles: [ "ticket:read" ] } ]
|
||||
|
||||
definitions:
|
||||
TaskForm:
|
||||
type: object
|
||||
required: [ name, type ]
|
||||
properties:
|
||||
name: { type: string, example: "Inform user" }
|
||||
type: { type: string, enum: [ task, input, automation ], example: "task" }
|
||||
done: { type: boolean }
|
||||
|
||||
owner: { type: string }
|
||||
data: { type: object }
|
||||
|
||||
# automation
|
||||
automation: { type: string }
|
||||
payload: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
# input
|
||||
schema: { type: object }
|
||||
|
||||
# workflow
|
||||
join: { type: boolean, example: false }
|
||||
next: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
|
||||
Task:
|
||||
type: object
|
||||
required: [ name, type, done, created ]
|
||||
properties:
|
||||
name: { type: string, example: "Inform user" }
|
||||
type: { type: string, enum: [ task, input, automation ], example: "task" }
|
||||
done: { type: boolean }
|
||||
|
||||
owner: { type: string }
|
||||
data: { type: object }
|
||||
|
||||
# automation
|
||||
automation: { type: string }
|
||||
payload: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
# input
|
||||
schema: { type: object }
|
||||
|
||||
# workflow
|
||||
join: { type: boolean, example: false }
|
||||
next: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
|
||||
TaskResponse:
|
||||
type: object
|
||||
required: [ name, type, done, created, order, active ]
|
||||
properties:
|
||||
name: { type: string, example: "Inform user" }
|
||||
type: { type: string, enum: [ task, input, automation ], example: "task" }
|
||||
done: { type: boolean }
|
||||
|
||||
owner: { type: string }
|
||||
data: { type: object }
|
||||
|
||||
# automation
|
||||
automation: { type: string }
|
||||
payload: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
# input
|
||||
schema: { type: object }
|
||||
|
||||
# workflow
|
||||
join: { type: boolean, example: false }
|
||||
next: { type: object, additionalProperties: { type: string } }
|
||||
|
||||
created: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
closed: { type: string, format: "date-time", example: "1985-04-12T23:20:50.52Z" }
|
||||
|
||||
# helper
|
||||
order: { type: number, format: "int64", example: 2 }
|
||||
active: { type: boolean, example: false }
|
||||
|
||||
TaskWithContext:
|
||||
type: object
|
||||
required: [ ticket_id, ticket_name, playbook_id, playbook_name, task_id, task ]
|
||||
properties:
|
||||
ticket_id: { type: number, format: "int64" }
|
||||
ticket_name: { type: string }
|
||||
playbook_id: { type: string }
|
||||
playbook_name: { type: string }
|
||||
task_id: { type: string }
|
||||
task: { $ref: '#/definitions/TaskResponse' }
|
||||
104
definition/templates.yaml
Normal file
104
definition/templates.yaml
Normal file
@@ -0,0 +1,104 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/templates:
|
||||
get:
|
||||
tags: [ "templates" ]
|
||||
summary: "List templates"
|
||||
operationId: "listTemplates"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/TicketTemplateResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- id: default
|
||||
name: Default
|
||||
schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"
|
||||
security: [ { roles: [ "template:read" ] } ]
|
||||
post:
|
||||
tags: [ "templates" ]
|
||||
summary: "Create a new template"
|
||||
operationId: "createTemplate"
|
||||
parameters:
|
||||
- { name: "template", in: "body", description: "New template", required: true, schema: { $ref: "#/definitions/TicketTemplateForm" }, x-example: { name: "My Template", schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketTemplateResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: "my-template"
|
||||
name: "My Template"
|
||||
schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"
|
||||
security: [ { roles: [ "template:write" ] } ]
|
||||
|
||||
/templates/{id}:
|
||||
get:
|
||||
tags: [ "templates" ]
|
||||
summary: "Get a single template"
|
||||
operationId: "getTemplate"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "default" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketTemplateResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: default
|
||||
name: Default
|
||||
schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Default\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"
|
||||
security: [ { roles: [ "template:read" ] } ]
|
||||
put:
|
||||
tags: [ "templates" ]
|
||||
summary: "Update an existing template"
|
||||
operationId: "updateTemplate"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "default" }
|
||||
- { name: "template", in: "body", description: "Template object that needs to be added", required: true, schema: { $ref: "#/definitions/TicketTemplateForm" }, x-example: { name: "My Template", schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketTemplateResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: default
|
||||
name: "My Template"
|
||||
schema: "{\n \"definitions\": {},\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://example.com/object1618746510.json\",\n \"title\": \"Event\",\n \"type\": \"object\",\n \"required\": [\n \"severity\",\n \"description\",\n \"tlp\"\n ],\n \"properties\": {\n \"severity\": {\n \"$id\": \"#root/severity\",\n \"title\": \"Severity\",\n \"type\": \"string\",\n \"default\": \"Medium\",\n \"nx-enum\": [\n \"Low\",\n \"Medium\",\n \"High\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"Low\",\n \"title\": \"Low\",\n \"icon\": \"mdi-chevron-up\"\n },\n {\n \"const\": \"Medium\",\n \"title\": \"Medium\",\n \"icon\": \"mdi-chevron-double-up\"\n },\n {\n \"const\": \"High\",\n \"title\": \"High\",\n \"icon\": \"mdi-chevron-triple-up\"\n }\n ]\n },\n \"tlp\": {\n \"$id\": \"#root/tlp\",\n \"title\": \"TLP\",\n \"type\": \"string\",\n \"nx-enum\": [\n \"White\",\n \"Green\",\n \"Amber\",\n \"Red\"\n ],\n \"x-cols\": 6,\n \"x-class\": \"pr-2\",\n \"x-display\": \"icon\",\n \"x-itemIcon\": \"icon\",\n \"oneOf\": [\n {\n \"const\": \"White\",\n \"title\": \"White\",\n \"icon\": \"mdi-alpha-w\"\n },\n {\n \"const\": \"Green\",\n \"title\": \"Green\",\n \"icon\": \"mdi-alpha-g\"\n },\n {\n \"const\": \"Amber\",\n \"title\": \"Amber\",\n \"icon\": \"mdi-alpha-a\"\n },\n {\n \"const\": \"Red\",\n \"title\": \"Red\",\n \"icon\": \"mdi-alpha-r\"\n }\n ]\n },\n \"description\": {\n \"$id\": \"#root/description\",\n \"title\": \"Description\",\n \"type\": \"string\",\n \"x-display\": \"textarea\",\n \"x-class\": \"pr-2\"\n }\n }\n}\n"
|
||||
|
||||
security: [ { roles: [ "template:write" ] } ]
|
||||
delete:
|
||||
tags: [ "templates" ]
|
||||
summary: "Delete a template"
|
||||
operationId: "deleteTemplate"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "default" }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "template:write" ] } ]
|
||||
|
||||
definitions:
|
||||
TicketTemplateForm:
|
||||
type: object
|
||||
required: [ name, schema ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
schema: { type: string }
|
||||
|
||||
TicketTemplate:
|
||||
type: object
|
||||
required: [ name, schema ]
|
||||
properties:
|
||||
name: { type: string }
|
||||
schema: { type: string }
|
||||
|
||||
TicketTemplateResponse:
|
||||
type: object
|
||||
required: [ id, name, schema ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string }
|
||||
schema: { type: string }
|
||||
1094
definition/tickets.yaml
Normal file
1094
definition/tickets.yaml
Normal file
File diff suppressed because it is too large
Load Diff
121
definition/tickettype.yaml
Normal file
121
definition/tickettype.yaml
Normal file
@@ -0,0 +1,121 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
|
||||
paths:
|
||||
/tickettypes:
|
||||
get:
|
||||
tags: [ "tickettypes" ]
|
||||
summary: "List tickettypes"
|
||||
operationId: "listTicketTypes"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/TicketTypeResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- { icon: "mdi-alert", id: "alert", name: "Alerts", default_template: "default", default_playbooks: [ ] }
|
||||
- { icon: "mdi-radioactive", id: "incident", name: "Incidents", default_template: "default", default_playbooks: [ ] }
|
||||
- { icon: "mdi-fingerprint", id: "investigation", name: "Forensic Investigations", default_template: "default", default_playbooks: [ ] }
|
||||
- { icon: "mdi-target", id: "hunt", name: "Threat Hunting", default_template: "default", default_playbooks: [ ] }
|
||||
security: [ { roles: [ "tickettype:read" ] } ]
|
||||
post:
|
||||
tags: [ "tickettypes" ]
|
||||
summary: "Create a new tickettype"
|
||||
operationId: "createTicketType"
|
||||
parameters:
|
||||
- { name: "tickettype", in: "body", description: "New tickettype", required: true, schema: { $ref: "#/definitions/TicketTypeForm" }, x-example: { name: "TI Tickets", icon: "mdi-newspaper-variant-outline", default_template: "default", default_playbooks: [ ] } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketTypeResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: "ti-tickets"
|
||||
name: "TI Tickets"
|
||||
icon: "mdi-newspaper-variant-outline"
|
||||
default_template: "default"
|
||||
default_playbooks: [ ]
|
||||
security: [ { roles: [ "tickettype:write" ] } ]
|
||||
|
||||
/tickettypes/{id}:
|
||||
get:
|
||||
tags: [ "tickettypes" ]
|
||||
summary: "Get a single tickettype"
|
||||
operationId: "getTicketType"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "TicketType ID", required: true, type: string, x-example: "alert" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketTypeResponse" }
|
||||
examples:
|
||||
test:
|
||||
icon: "mdi-alert"
|
||||
id: "alert"
|
||||
name: "Alerts"
|
||||
default_template: "default"
|
||||
default_playbooks: [ ]
|
||||
security: [ { roles: [ "tickettype:read" ] } ]
|
||||
put:
|
||||
tags: [ "tickettypes" ]
|
||||
summary: "Update an existing tickettype"
|
||||
operationId: "updateTicketType"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "TicketType ID", required: true, type: string, x-example: "alert" }
|
||||
- { name: "tickettype", in: "body", description: "TicketType object that needs to be added", required: true, schema: { $ref: "#/definitions/TicketTypeForm" }, x-example: { icon: "mdi-bell", id: "alert", name: "Alerts", default_template: "default", default_playbooks: [ ] } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/TicketTypeResponse" }
|
||||
examples:
|
||||
test:
|
||||
icon: "mdi-bell"
|
||||
id: "alert"
|
||||
name: "Alerts"
|
||||
default_template: "default"
|
||||
default_playbooks: [ ]
|
||||
|
||||
security: [ { roles: [ "tickettype:write" ] } ]
|
||||
delete:
|
||||
tags: [ "tickettypes" ]
|
||||
summary: "Delete a tickettype"
|
||||
operationId: "deleteTicketType"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "TicketType ID", required: true, type: string, x-example: "alert" }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "tickettype:write" ] } ]
|
||||
|
||||
definitions:
|
||||
TicketTypeForm:
|
||||
type: object
|
||||
required: [ name, icon, default_template, default_playbooks ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
icon: { type: string }
|
||||
name: { type: string }
|
||||
default_template: { type: string }
|
||||
default_playbooks: { type: array, items: { type: string } }
|
||||
default_groups: { type: array, items: { type: string } }
|
||||
|
||||
TicketType:
|
||||
type: object
|
||||
required: [ name, icon, default_template, default_playbooks ]
|
||||
properties:
|
||||
icon: { type: string }
|
||||
name: { type: string }
|
||||
default_template: { type: string }
|
||||
default_playbooks: { type: array, items: { type: string } }
|
||||
default_groups: { type: array, items: { type: string } }
|
||||
|
||||
TicketTypeResponse:
|
||||
type: object
|
||||
required: [ id, name, icon, default_template, default_playbooks ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
icon: { type: string }
|
||||
name: { type: string }
|
||||
default_template: { type: string }
|
||||
default_playbooks: { type: array, items: { type: string } }
|
||||
default_groups: { type: array, items: { type: string } }
|
||||
94
definition/userdata.yaml
Normal file
94
definition/userdata.yaml
Normal file
@@ -0,0 +1,94 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/currentuserdata:
|
||||
get:
|
||||
tags: [ "userdata" ]
|
||||
summary: "Get current user data"
|
||||
operationId: "currentUserData"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserDataResponse" }
|
||||
examples:
|
||||
test: { id: bob, name: "Bob Bad", email: "bob@example.org" }
|
||||
security: [ { roles: [ "currentuserdata:read" ] } ]
|
||||
put:
|
||||
tags: [ "userdata" ]
|
||||
summary: "Update current user data"
|
||||
operationId: "updateCurrentUserData"
|
||||
parameters:
|
||||
- { name: "userdata", in: "body", description: "User data object that needs to be added", required: true, schema: { $ref: "#/definitions/UserData" }, x-example: { name: "Bob Bad", email: "bob@example.org" } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserDataResponse" }
|
||||
examples:
|
||||
test: { id: bob, name: "Bob Bad", email: "bob@example.org" }
|
||||
security: [ { roles: [ "currentuserdata:write" ] } ]
|
||||
|
||||
/userdata:
|
||||
get:
|
||||
tags: [ "userdata" ]
|
||||
summary: "List userdata"
|
||||
operationId: "listUserData"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/UserDataResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- { id: bob, name: "Bob Bad", email: "bob@example.org" }
|
||||
security: [ { roles: [ "userdata:read" ] } ]
|
||||
|
||||
/userdata/{id}:
|
||||
get:
|
||||
tags: [ "userdata" ]
|
||||
summary: "Get a single user data"
|
||||
operationId: "getUserData"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "User Data ID", required: true, type: string, x-example: "bob" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserDataResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: bob
|
||||
name: "Bob Bad"
|
||||
email: "bob@example.org"
|
||||
security: [ { roles: [ "userdata:read" ] } ]
|
||||
put:
|
||||
tags: [ "userdata" ]
|
||||
summary: "Update an existing user data"
|
||||
operationId: "updateUserData"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "User Data ID", required: true, type: string, x-example: "bob" }
|
||||
- { name: "userdata", in: "body", description: "User data object that needs to be added", required: true, schema: { $ref: "#/definitions/UserData" }, x-example: { name: "Bob Bad", email: "bob@example.org", blocked: false } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserDataResponse" }
|
||||
examples:
|
||||
test: { id: bob, name: "Bob Bad", email: "bob@example.org" }
|
||||
security: [ { roles: [ "userdata:write" ] } ]
|
||||
|
||||
definitions:
|
||||
UserData:
|
||||
type: object
|
||||
properties:
|
||||
name: { type: string, x-example: "Robert Smith" }
|
||||
email: { type: string, x-example: "bob@example.org" }
|
||||
image: { type: string, x-display: "custom-avatar" }
|
||||
timeformat: { title: "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", type: string }
|
||||
|
||||
UserDataResponse:
|
||||
type: object
|
||||
required: [ id ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
name: { type: string, x-example: "Robert Smith" }
|
||||
email: { type: string, x-example: "bob@example.org" }
|
||||
image: { type: string, x-display: "custom-avatar" }
|
||||
timeformat: { title: "Time Format (https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens)", type: string }
|
||||
122
definition/users.yaml
Normal file
122
definition/users.yaml
Normal file
@@ -0,0 +1,122 @@
|
||||
swagger: "2.0"
|
||||
info: { version: "", title: "" }
|
||||
|
||||
paths:
|
||||
/currentuser:
|
||||
get:
|
||||
tags: [ "users" ]
|
||||
summary: "Get current user"
|
||||
operationId: "currentUser"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserResponse" }
|
||||
examples:
|
||||
test: { id: bob, roles: [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: false }
|
||||
security: [ { roles: [ "currentuser:read" ] } ]
|
||||
|
||||
/users:
|
||||
get:
|
||||
tags: [ "users" ]
|
||||
summary: "List users"
|
||||
operationId: "listUsers"
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { type: array, items: { $ref: "#/definitions/UserResponse" } }
|
||||
examples:
|
||||
test:
|
||||
- { id: bob, blocked: false, roles: [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], apikey: false }
|
||||
- { id: script, roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: true }
|
||||
security: [ { roles: [ "user:read" ] } ]
|
||||
post:
|
||||
tags: [ "users" ]
|
||||
summary: "Create user"
|
||||
operationId: "createUser"
|
||||
parameters:
|
||||
- { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { id: "syncscript", roles: [ "analyst" ] } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/NewUserResponse" }
|
||||
examples:
|
||||
test: { id: "syncscript", roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read" ], secret: "v39bOuobnlEljfWzjAgoKzhmnh1xSMxH", blocked: false }
|
||||
security: [ { roles: [ "user:write" ] } ]
|
||||
/users/{id}:
|
||||
get:
|
||||
tags: [ "users" ]
|
||||
summary: "Get a single user"
|
||||
operationId: "getUser"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "user ID", required: true, type: string, x-example: "script" }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserResponse" }
|
||||
examples:
|
||||
test: { id: "script", roles: [ "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ], blocked: false, apikey: true }
|
||||
security: [ { roles: [ "user:read" ] } ]
|
||||
put:
|
||||
tags: [ "users" ]
|
||||
summary: "Update user"
|
||||
operationId: "updateUser"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "Template ID", required: true, type: string, x-example: "bob" }
|
||||
- { name: "user", in: "body", description: "user object that needs to be added", required: true, schema: { $ref: "#/definitions/UserForm" }, x-example: { roles: [ "analyst", "admin" ] } }
|
||||
responses:
|
||||
"200":
|
||||
description: "successful operation"
|
||||
schema: { $ref: "#/definitions/UserResponse" }
|
||||
examples:
|
||||
test:
|
||||
id: bob
|
||||
roles: [ "admin:backup:read", "admin:backup:restore", "admin:group:write", "admin:job:read", "admin:job:write", "admin:log:read", "admin:ticket:delete", "admin:user:write", "admin:userdata:read", "admin:userdata:write", "analyst:automation:read", "analyst:currentsettings:write", "analyst:currentuser:read", "analyst:currentuserdata:read", "analyst:file", "analyst:group:read", "analyst:playbook:read", "analyst:rule:read", "analyst:settings:read", "analyst:template:read", "analyst:ticket:read", "analyst:ticket:write", "analyst:tickettype:read", "analyst:user:read", "engineer:automation:write", "engineer:playbook:write", "engineer:rule:write", "engineer:template:write", "engineer:tickettype:write" ]
|
||||
apikey: false
|
||||
blocked: false
|
||||
security: [ { roles: [ "user:write" ] } ]
|
||||
delete:
|
||||
tags: [ "users" ]
|
||||
summary: "Delete user"
|
||||
operationId: "deleteUser"
|
||||
parameters:
|
||||
- { name: "id", in: "path", description: "user ID", required: true, type: string, x-example: "script" }
|
||||
responses:
|
||||
"204": { description: "successful operation" }
|
||||
security: [ { roles: [ "user:write" ] } ]
|
||||
|
||||
definitions:
|
||||
UserForm:
|
||||
type: object
|
||||
required: [ id, blocked, roles, apikey ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
blocked: { type: boolean }
|
||||
apikey: { type: boolean }
|
||||
roles: { type: array, items: { type: string } }
|
||||
|
||||
User:
|
||||
type: object
|
||||
required: [ blocked, apikey, roles ]
|
||||
properties:
|
||||
blocked: { type: boolean }
|
||||
apikey: { type: boolean }
|
||||
roles: { type: array, items: { type: string } }
|
||||
sha256: { type: string } # for api keys
|
||||
|
||||
UserResponse:
|
||||
type: object
|
||||
required: [ id, blocked, roles, apikey ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
blocked: { type: boolean }
|
||||
apikey: { type: boolean }
|
||||
roles: { type: array, items: { type: string } }
|
||||
|
||||
NewUserResponse:
|
||||
type: object
|
||||
required: [ id, blocked, roles ]
|
||||
properties:
|
||||
id: { type: string }
|
||||
blocked: { type: boolean }
|
||||
roles: { type: array, items: { type: string } }
|
||||
secret: { type: string }
|
||||
Reference in New Issue
Block a user