openapi: 3.0.0 info: version: 1.3.0 title: Cerebrate Project API description: | Cerebrate is an open-source platform meant to act as a trusted contact information provider and interconnection orchestrator for other security tools. servers: - url: https://cerebrate.local tags: - name: Individuals description: "Individuals are natural persons. They are meant to describe the basic information about an individual that may or may not be a user of this community. Users in genral require an individual object to identify the person behind them - however, no user account is required to store information about an individual. Individuals can have affiliations to organisations and broods as well as cryptographic keys, using which their messages can be verified and which can be used to securely contact them." - name: Users description: "Users enrolled in this Cerebrate instance." - name: Organisations description: "Organisations can be equivalent to legal entities or specific individual teams within such entities. Their purpose is to relate individuals to their affiliations and for release control of information using the Trust Circles." - name: Tags description: "Tags can be attached to entity to quickly classify them, allowing further filtering and searches." - name: Inbox description: "Inbox messages represent A list of requests to be manually processed." paths: /api/v1/individuals/index: get: summary: "Get individuals list" operationId: getIndividuals tags: - Individuals parameters: - $ref: "#/components/parameters/quickFilter" responses: "200": $ref: "#/components/responses/IndividualListResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/individuals/add: post: summary: "Add individual" operationId: addIndividual tags: - Users requestBody: $ref: "#/components/requestBodies/AddIndividualRequest" responses: "200": $ref: "#/components/responses/IndividualResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/individuals/edit/{individualId}: put: summary: "Edit individual" operationId: editIndividual tags: - Individuals parameters: - $ref: "#/components/parameters/individualId" requestBody: $ref: "#/components/requestBodies/EditIndividualRequest" responses: "200": $ref: "#/components/responses/IndividualResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/individuals/delete/{individualId}: delete: summary: "Delete individual by ID" operationId: deleteIndividualById tags: - Individuals parameters: - $ref: "#/components/parameters/individualId" responses: "200": $ref: "#/components/responses/IndividualResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/index: get: summary: "Get users list" operationId: getUsers tags: - Users parameters: - $ref: "#/components/parameters/quickFilter" responses: "200": $ref: "#/components/responses/UserListResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/view: get: summary: "Get information about the current user" operationId: viewUserMe tags: - Users responses: "200": $ref: "#/components/responses/UserResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/view/{userId}: get: summary: "Get information of a user by id" operationId: viewUserById tags: - Users parameters: - $ref: "#/components/parameters/userId" responses: "200": $ref: "#/components/responses/UserResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/add: post: summary: "Add user" operationId: addUser tags: - Users requestBody: $ref: "#/components/requestBodies/AddUserRequest" responses: "200": $ref: "#/components/responses/UserResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/edit: put: summary: "Edit current user" operationId: editUser tags: - Users requestBody: $ref: "#/components/requestBodies/EditUserRequest" responses: "200": $ref: "#/components/responses/UserResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/edit/{userId}: put: summary: "Edit current user" operationId: editUserById tags: - Users parameters: - $ref: "#/components/parameters/userId" requestBody: $ref: "#/components/requestBodies/EditUserRequest" responses: "200": $ref: "#/components/responses/UserResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/users/delete/{userId}: delete: summary: "Delete user by ID" operationId: deleteUserById tags: - Users parameters: - $ref: "#/components/parameters/userId" responses: "200": $ref: "#/components/responses/UserResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/add: post: summary: "Add organisation" operationId: addOrganisation tags: - Organisations requestBody: $ref: "#/components/requestBodies/AddOrganisationRequest" responses: "200": $ref: "#/components/responses/OrganisationResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/edit/{organisationId}: put: summary: "Edit organisation" operationId: editOrganisation tags: - Organisations parameters: - $ref: "#/components/parameters/organisationId" requestBody: $ref: "#/components/requestBodies/EditOrganisationRequest" responses: "200": $ref: "#/components/responses/OrganisationResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/index: get: summary: "Get organisations" operationId: getOrganisations tags: - Organisations parameters: - $ref: "#/components/parameters/quickFilter" responses: "200": $ref: "#/components/responses/OrganisationListResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/view/{organisationId}: get: summary: "View organisation by ID" operationId: getOrganisationById tags: - Organisations parameters: - $ref: "#/components/parameters/organisationId" responses: "200": $ref: "#/components/responses/OrganisationResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/delete/{organisationId}: delete: summary: "Delete organisation by ID" operationId: deleteOrganisationById tags: - Organisations parameters: - $ref: "#/components/parameters/organisationId" responses: "200": $ref: "#/components/responses/OrganisationResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/tag/{organisationId}: post: summary: "Tag organisation by ID" operationId: tagOrganisationById tags: - Organisations parameters: - $ref: "#/components/parameters/organisationId" requestBody: $ref: "#/components/requestBodies/TagOrganisationRequest" responses: "200": $ref: "#/components/responses/OrganisationResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/organisations/untag/{organisationId}: post: summary: "Remove organisation tag by ID" operationId: untagOrganisationById tags: - Organisations parameters: - $ref: "#/components/parameters/organisationId" requestBody: $ref: "#/components/requestBodies/UntagOrganisationRequest" responses: "200": $ref: "#/components/responses/OrganisationResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/tags/index: get: summary: "Get tags list" operationId: getTags tags: - Tags parameters: - $ref: "#/components/parameters/quickFilter" responses: "200": $ref: "#/components/responses/TagListResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/inbox/index: get: summary: "Get inbox list" operationId: getinbox tags: - Inbox parameters: - $ref: "#/components/parameters/quickFilter" responses: "200": $ref: "#/components/responses/InboxListResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" /api/v1/inbox/createEntry/User/Registration: post: summary: "Create user registration inbox entry" operationId: createInboxEntry tags: - Inbox requestBody: $ref: "#/components/requestBodies/CreateUserRegistrationInboxEntryRequest" responses: "200": $ref: "#/components/responses/CreateUserRegistrationInboxEntryResponse" "403": $ref: "#/components/responses/UnauthorizedApiErrorResponse" "405": $ref: "#/components/responses/MethodNotAllowedApiErrorResponse" default: $ref: "#/components/responses/ApiErrorResponse" components: schemas: # General UUID: type: string format: uuid maxLength: 36 example: "c99506a6-1255-4b71-afa5-7b8ba48c3b1b" ID: type: integer format: int32 example: 1 DateTime: type: string format: datetime example: "2022-01-05T11:19:26+00:00" Email: type: string format: email example: "user@example.com" # Individuals IndividualFirstName: type: string example: "John" IndividualLastName: type: string example: "Doe" IndividualFullName: type: string example: "John Doe" IndividualPosition: type: string example: "Security Analyst" Individual: type: object properties: id: $ref: "#/components/schemas/ID" uuid: $ref: "#/components/schemas/UUID" email: $ref: "#/components/schemas/Email" first_name: $ref: "#/components/schemas/IndividualFirstName" last_name: $ref: "#/components/schemas/IndividualLastName" full_name: $ref: "#/components/schemas/IndividualFullName" position: $ref: "#/components/schemas/IndividualPosition" tags: $ref: "#/components/schemas/TagList" aligments: $ref: "#/components/schemas/AligmentList" created: $ref: "#/components/schemas/DateTime" modified: $ref: "#/components/schemas/DateTime" # Users Username: type: string example: "admin" IndividualList: type: array items: $ref: "#/components/schemas/Individual" User: type: object properties: id: $ref: "#/components/schemas/ID" uuid: $ref: "#/components/schemas/UUID" username: $ref: "#/components/schemas/Username" role_id: $ref: "#/components/schemas/ID" individual_id: $ref: "#/components/schemas/ID" disabled: type: boolean created: $ref: "#/components/schemas/DateTime" modified: $ref: "#/components/schemas/DateTime" organisation_id: $ref: "#/components/schemas/ID" UserList: type: array items: $ref: "#/components/schemas/User" # Organisations OrganisationName: type: string OrganisationUrl: type: string OrganisationSector: type: string nullable: true OrganisationType: type: string nullable: true OrganisationContacts: type: string nullable: true OrganisationNationality: type: string nullable: true Organisation: type: object properties: id: $ref: "#/components/schemas/ID" uuid: $ref: "#/components/schemas/UUID" name: $ref: "#/components/schemas/OrganisationName" url: $ref: "#/components/schemas/OrganisationUrl" nationality: $ref: "#/components/schemas/OrganisationNationality" sector: $ref: "#/components/schemas/OrganisationSector" type: $ref: "#/components/schemas/OrganisationType" contacts: $ref: "#/components/schemas/OrganisationContacts" created: $ref: "#/components/schemas/DateTime" modified: $ref: "#/components/schemas/DateTime" tags: $ref: "#/components/schemas/TagList" aligments: $ref: "#/components/schemas/AligmentList" OrganisationList: type: array items: $ref: "#/components/schemas/Organisation" # Tags TagName: type: string example: "white" TagNamespace: type: string nullable: true example: "tlp" TagPredicate: type: string nullable: true TagValue: type: string nullable: true TagColour: type: string example: "FFFFFF" TagTextColour: type: string example: "white" Tag: type: object properties: id: $ref: "#/components/schemas/ID" name: $ref: "#/components/schemas/TagName" namespace: $ref: "#/components/schemas/TagNamespace" predicate: $ref: "#/components/schemas/TagPredicate" value: $ref: "#/components/schemas/TagValue" colour: $ref: "#/components/schemas/TagColour" text_colour: $ref: "#/components/schemas/TagTextColour" counter: type: integer created: $ref: "#/components/schemas/DateTime" modified: $ref: "#/components/schemas/DateTime" TagList: type: array items: $ref: "#/components/schemas/Tag" # Alignments Alignment: type: object AligmentList: type: array items: $ref: "#/components/schemas/Alignment" # Roles RoleName: type: string maxLength: 255 example: "admin" Role: type: object properties: id: $ref: "#/components/schemas/ID" name: $ref: "#/components/schemas/RoleName" is_default: type: boolean perm_admin: type: boolean perm_sync: type: boolean perm_org_admin: type: boolean # Inbox InboxScope: type: string enum: - "User" - "LocalTool" InboxAction: type: string enum: - "Registration" - "IncomingConnectionRequest" - "AcceptedRequest" - "DeclinedRequest" InboxTitle: type: string InboxOrigin: type: string InboxComment: type: string nullable: true InboxDescription: type: string nullable: true Inbox: type: object properties: id: $ref: "#/components/schemas/ID" uuid: $ref: "#/components/schemas/UUID" scope: $ref: "#/components/schemas/InboxScope" action: $ref: "#/components/schemas/InboxAction" title: $ref: "#/components/schemas/InboxTitle" origin: $ref: "#/components/schemas/InboxOrigin" comment: $ref: "#/components/schemas/InboxComment" description: $ref: "#/components/schemas/InboxDescription" user_id: $ref: "#/components/schemas/ID" created: $ref: "#/components/schemas/DateTime" modified: $ref: "#/components/schemas/DateTime" UserRegistrationInbox: type: object allOf: - $ref: "#/components/schemas/Inbox" - type: object properties: data: type: object properties: email: type: string format: email password: type: string user: $ref: "#/components/schemas/User" local_tool_connector_name: type: string nullable: true IncomingConnectionRequestInbox: type: object allOf: - $ref: "#/components/schemas/Inbox" - type: object properties: data: type: object properties: connectorName: type: string enum: - "MispConnector" cerebrateURL: type: string example: "http://192.168.0.1" local_tool_id: type: integer remote_tool_id: type: integer InboxList: type: array items: anyOf: - $ref: "#/components/schemas/UserRegistrationInbox" - $ref: "#/components/schemas/IncomingConnectionRequestInbox" # Errors ApiError: type: object required: - message - url - code properties: message: type: string url: type: string example: "/api/v1/users" code: type: integer example: 500 UnauthorizedApiError: type: object required: - message - url - code properties: message: type: string example: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header." url: type: string example: "/api/v1/users" code: type: integer example: 403 MethodNotAllowedApiError: type: object required: - message - url - code properties: message: type: string example: "You do not have permission to use this functionality." url: type: string example: "/api/v1/users/index" code: type: integer example: 405 NotFoundApiError: type: object required: - message - url - code properties: message: type: string example: "Invalid user" url: type: string example: "/api/v1/users/users/view/1234" code: type: integer example: 404 parameters: individualId: name: individualId in: path description: "Numeric ID of the User" required: true schema: $ref: "#/components/schemas/ID" userId: name: userId in: path description: "Numeric ID of the User" required: true schema: $ref: "#/components/schemas/ID" organisationId: name: organisationId in: path description: "Numeric ID of the Organisation" required: true schema: $ref: "#/components/schemas/ID" quickFilter: name: quickFilter in: query description: "Quick filter used to match multiple attributes such as name, description, emails, etc." schema: type: string example: "user@example.com" securitySchemes: ApiKeyAuth: type: apiKey in: header name: Authorization description: | The authorization is performed by using the following header in the HTTP requests: Authorization: YOUR_API_KEY requestBodies: # Individuals AddIndividualRequest: required: true content: application/json: schema: type: object properties: uuid: $ref: "#/components/schemas/UUID" email: $ref: "#/components/schemas/IndividualLastName" first_name: $ref: "#/components/schemas/IndividualFirstName" last_name: type: boolean position: $ref: "#/components/schemas/IndividualPosition" EditIndividualRequest: required: true content: application/json: schema: type: object properties: uuid: $ref: "#/components/schemas/UUID" email: $ref: "#/components/schemas/IndividualLastName" first_name: $ref: "#/components/schemas/IndividualFirstName" last_name: type: boolean position: $ref: "#/components/schemas/IndividualPosition" # Users AddUserRequest: required: true content: application/json: schema: type: object properties: individual_id: $ref: "#/components/schemas/ID" organisation_id: $ref: "#/components/schemas/ID" role_id: $ref: "#/components/schemas/ID" disabled: type: boolean username: $ref: "#/components/schemas/Username" password: type: string EditUserRequest: required: true content: application/json: schema: type: object properties: id: $ref: "#/components/schemas/ID" individual_id: $ref: "#/components/schemas/ID" organisation_id: $ref: "#/components/schemas/ID" role_id: $ref: "#/components/schemas/ID" disabled: type: boolean username: $ref: "#/components/schemas/Username" password: type: string # Organisations AddOrganisationRequest: required: true content: application/json: schema: type: object properties: uuid: $ref: "#/components/schemas/UUID" name: $ref: "#/components/schemas/OrganisationName" url: $ref: "#/components/schemas/OrganisationUrl" nationality: $ref: "#/components/schemas/OrganisationNationality" sector: $ref: "#/components/schemas/OrganisationSector" type: $ref: "#/components/schemas/OrganisationType" contacts: $ref: "#/components/schemas/OrganisationContacts" EditOrganisationRequest: required: true content: application/json: schema: type: object properties: uuid: $ref: "#/components/schemas/UUID" name: $ref: "#/components/schemas/OrganisationName" url: $ref: "#/components/schemas/OrganisationUrl" nationality: $ref: "#/components/schemas/OrganisationNationality" sector: $ref: "#/components/schemas/OrganisationSector" type: $ref: "#/components/schemas/OrganisationType" contacts: $ref: "#/components/schemas/OrganisationContacts" TagOrganisationRequest: required: true content: application/json: schema: type: object properties: tag_list: type: string description: "Stringified JSON array of the tag names to add." example: '["red"]' UntagOrganisationRequest: required: true content: application/json: schema: type: object properties: tag_list: type: string description: "Stringified JSON array of the tag names to remove." example: '["red"]' # Inbox CreateUserRegistrationInboxEntryRequest: description: "Create user registration inbox entry request" content: application/json: schema: type: object properties: email: type: string format: email password: type: string responses: # Individuals IndividualResponse: description: "Individual response" content: application/json: schema: $ref: "#/components/schemas/Individual" IndividualListResponse: description: "Individuals list response" content: application/json: schema: $ref: "#/components/schemas/IndividualList" # Users UserResponse: description: "User response" content: application/json: schema: $ref: "#/components/schemas/User" UserListResponse: description: "Users list response" content: application/json: schema: $ref: "#/components/schemas/UserList" # Organisations OrganisationResponse: description: "Organisation response" content: application/json: schema: $ref: "#/components/schemas/Organisation" OrganisationListResponse: description: "Organisations list response" content: application/json: schema: $ref: "#/components/schemas/OrganisationList" # Tags TagResponse: description: "Tag response" content: application/json: schema: $ref: "#/components/schemas/Tag" TagListResponse: description: "Tags list response" content: application/json: schema: $ref: "#/components/schemas/TagList" # Inbox UserRegistrationInboxResponse: description: "User registration inbox response" content: application/json: schema: $ref: "#/components/schemas/UserRegistrationInbox" IncomingConnectionRequestInboxResponse: description: "Incoming connection request inbox response" content: application/json: schema: $ref: "#/components/schemas/IncomingConnectionRequestInbox" InboxListResponse: description: "Inbox list response" content: application/json: schema: $ref: "#/components/schemas/InboxList" CreateUserRegistrationInboxEntryResponse: description: "Inbox response" content: application/json: schema: type: object properties: data: allOf: - $ref: "#/components/schemas/UserRegistrationInbox" - properties: local_tool_connector_name: type: string nullable: true success: type: boolean message: type: string example: "User account creation requested. Please wait for an admin to approve your account." errors: type: array items: type: object # Errors ApiErrorResponse: description: "Unexpected API error" content: application/json: schema: $ref: "#/components/schemas/ApiError" UnauthorizedApiErrorResponse: description: "Authentication failed. Please make sure you pass the API key of an API enabled user along in the Authorization header." content: application/json: schema: $ref: "#/components/schemas/UnauthorizedApiError" MethodNotAllowedApiErrorResponse: description: "Method not allowed. Your User Role is not allowed to access this resource." content: application/json: schema: $ref: "#/components/schemas/MethodNotAllowedApiError" security: - ApiKeyAuth: []