[Backend] Introduce GraphQL resources for project-level exclusions
Overview
While we intend to have project-level exclusions managed via the UI, we still want to provide the ability for users to control their exclusions via GraphQL resources. This can be especially helpful in situations where customers manage the exclusions either via our terraform provider or through some other automated workflow.
Implementation Plan
Below is a list of tasks to achieve the desired outcome of this issue.
-
Introduce a new GraphQL type, eg. ProjectSecurityExclusionType
and add it toProjectType
. -
Introduce a new GraphQL resolver, eg. ProjectSecurityExclusionResolver
. -
Introduce a new GraphQL enum, e.g. ExclusionTypeEnum
. -
Introduce a new GraphQL enum, e.g. ExclusionScannerEnum
. -
Introduce a new GraphQL query to retrieve all project-level exclusions. -
Consider introducing a new GraphQL query to retrieve one project-level exclusion. -
Introduce a new GraphQL fragment, e.g. ProjectSecurityExclusionFragment
. -
Introduce GraphQL mutations to: -
Add a new exclusion to a project, e.g. ProjectSecurityExclusionCreateMutation
. -
Update an existing exclusion of a project, e.g. ProjectSecurityExclusionUpdateMutation
. -
Delete an existing exclusion of a project, e.g. ProjectSecurityExclusionDeleteMutation
.
-
-
Add appropriate documentation for all GraphQL resources.
Example Interface
Below is an example of the GraphQL API interface we seek to provide so frontend can build the UI to manage exclusions.
1. Enums and Fragment
enum ExclusionTypeEnum {
PATH
PATTERN
RAW_VALUE
RULE
}
enum ExclusionScannerEnum {
SECRET_PUSH_PROTECTION
}
fragment ProjectSecurityExclusionFragment on ProjectSecurityExclusion {
id: ProjectSecurityExclusionID
scanner: ExclusionScannerEnum
type: ExclusionTypeEnum
value: String
description: String
active: Boolean
createdAt: TimeType
updatedAt: TimeType
}
Project.securityExclusions
2. Query: query ProjectSecurityExclusions($fullPath: ID!, $first: Int) {
project(id: $fullPath) {
id
securityExclusions(first: $first) {
nodes {
...ProjectSecurityExclusionFragment
}
}
}
}
Considerations
- We need to support standard pagination params:
before: String
,after: String
,first: Int
, andlast: Int
. - Consider implementing another query
Project.securityExclusion
which can be used to retrieve a single exclusion.
query ProjectSecurityExclusion($fullPath: ID!, $first: Int) {
project(id: $fullPath) {
id
securityExclusion(id: ProjectSecurityExclusionID!) {
...ProjectSecurityExclusionFragment
}
}
}
3. Mutations
ProjectSecurityExclusionCreate
3.1 Mutation
mutation projectSecurityExclusionCreate($input: ProjectSecurityExclusionCreateInput!) {
projectSecurityExclusionCreate(input: $input) {
securityExclusion {
...ProjectSecurityExclusionFragment
}
errors
}
}
input ProjectSecurityExclusionCreateInput {
projectPath: ID!
scanner: ExclusionScannerEnum!
type: ExclusionTypeEnum!
value: String!
description: String
active: Boolean!
}
ProjectSecurityExclusionUpdate
3.2 Mutation mutation projectSecurityExclusionUpdate($input: ProjectSecurityExclusionUpdateInput!) {
projectSecurityExclusionUpdate(input: $input) {
securityExclusion {
...ProjectSecurityExclusionFragment
}
errors
}
}
input ProjectSecurityExclusionUpdateInput {
id: ProjectSecurityExclusionID!
scanner: ExclusionScannerEnum
type: ExclusionTypeEnum
active: Boolean
description: String
value: String
}
ProjectSecurityExclusionDelete
3.3 Mutation mutation projectSecurityExclusionDelete($input: ProjectSecurityExclusionDeleteInput!) {
projectSecurityExclusionDelete(input: $input) {
errors
}
}
input ProjectSecurityExclusionDeleteInput {
id: ProjectSecurityExclusionID!
}
Edited by Ahmed Hemdan