Skip to content

Commit

Permalink
Merge branch 'main' into BED-4852-oidc-delete-endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mvlipka committed Oct 24, 2024
2 parents 517f1e3 + 327cc34 commit 923a124
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 10 deletions.
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ BH_POSTGRES_DB=bloodhound
BH_POSTGRES_VOLUME=bh-postgres-data
BH_POSTGRES_PORT=127.0.0.1:6543

# Authentik SSO IdP, authentik Worker, authentik Postgres
# Some env variables are reused in multiple authentik services
ATK_BH_PG_USER=authentik
ATK_BH_PG_DB=authentik
ATK_BH_PG_PASS=bloodhoundcommunityedition
ATK_BH_SECRET=bloodhoundcommunityedition
COMPOSE_PORT_HTTP=127.0.0.1:9000
COMPOSE_PORT_HTTPS=127.0.0.1:9443

# Integration Postgres
INTEGRATION_POSTGRES_USER=bloodhound
INTEGRATION_POSTGRES_PASSWORD=bloodhoundcommunityedition
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/vuln-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ jobs:
uses: actions/checkout@v3

- name: Run vulnerability scanner
uses: aquasecurity/trivy-action@0.24.0
uses: aquasecurity/trivy-action@0.28.0
with:
scan-type: 'repo'
scan-ref: './'
severity: 'CRITICAL,HIGH'
exit-code: '1'
ignore-unfixed: true
env:
TRIVY_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-db,public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: ghcr.io/aquasecurity/trivy-java-db,public.ecr.aws/aquasecurity/trivy-java-db

6 changes: 3 additions & 3 deletions cmd/api/src/api/registration/v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ func NewV2API(cfg config.Configuration, resources v2.Resources, routerInst *rout
// Collection File Upload API
routerInst.GET("/api/v2/file-upload", resources.ListFileUploadJobs).RequireAuth()
routerInst.GET("/api/v2/file-upload/accepted-types", resources.ListAcceptedFileUploadTypes).RequireAuth()
routerInst.POST("/api/v2/file-upload/start", resources.StartFileUploadJob).RequirePermissions(permissions.GraphDBWrite)
routerInst.POST(fmt.Sprintf("/api/v2/file-upload/{%s}", v2.FileUploadJobIdPathParameterName), resources.ProcessFileUpload).RequirePermissions(permissions.GraphDBWrite)
routerInst.POST(fmt.Sprintf("/api/v2/file-upload/{%s}/end", v2.FileUploadJobIdPathParameterName), resources.EndFileUploadJob).RequirePermissions(permissions.GraphDBWrite)
routerInst.POST("/api/v2/file-upload/start", resources.StartFileUploadJob).RequirePermissions(permissions.GraphDBIngest)
routerInst.POST(fmt.Sprintf("/api/v2/file-upload/{%s}", v2.FileUploadJobIdPathParameterName), resources.ProcessFileUpload).RequirePermissions(permissions.GraphDBIngest)
routerInst.POST(fmt.Sprintf("/api/v2/file-upload/{%s}/end", v2.FileUploadJobIdPathParameterName), resources.EndFileUploadJob).RequirePermissions(permissions.GraphDBIngest)

router.With(middleware.DefaultRateLimitMiddleware,
// Version API
Expand Down
3 changes: 3 additions & 0 deletions cmd/api/src/auth/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type PermissionSet struct {

CollectionManageJobs model.Permission

GraphDBIngest model.Permission
GraphDBMutate model.Permission
GraphDBRead model.Permission
GraphDBWrite model.Permission
Expand All @@ -65,6 +66,7 @@ func (s PermissionSet) All() model.Permissions {
s.ClientsRead,
s.ClientsTasking,
s.CollectionManageJobs,
s.GraphDBIngest,
s.GraphDBMutate,
s.GraphDBRead,
s.GraphDBWrite,
Expand Down Expand Up @@ -96,6 +98,7 @@ func Permissions() PermissionSet {

CollectionManageJobs: model.NewPermission("collection", "ManageJobs"),

GraphDBIngest: model.NewPermission("graphdb", "Ingest"),
GraphDBMutate: model.NewPermission("graphdb", "Mutate"),
GraphDBRead: model.NewPermission("graphdb", "Read"),
GraphDBWrite: model.NewPermission("graphdb", "Write"),
Expand Down
3 changes: 2 additions & 1 deletion cmd/api/src/auth/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func Roles() map[string]RoleTemplate {
Description: "Used for data collection clients, can post data but cannot read data",
Permissions: model.Permissions{
permissions.ClientsTasking,
permissions.GraphDBWrite,
permissions.GraphDBIngest,
},
},
RoleUser: {
Expand Down Expand Up @@ -87,6 +87,7 @@ func Roles() map[string]RoleTemplate {
permissions.ClientsRead,
permissions.ClientsTasking,
permissions.CollectionManageJobs,
permissions.GraphDBIngest,
permissions.GraphDBWrite,
permissions.GraphDBRead,
permissions.SavedQueriesRead,
Expand Down
14 changes: 13 additions & 1 deletion cmd/api/src/auth/role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,26 @@ func testRoleAccess(t *testing.T, roleName string) {
userClient, ok := lab.Unpack(harness, userClientFixture)
assert.True(ok)

_, err := userClient.CreateFileUploadTask()
_, err := userClient.CreateAssetGroup(v2.CreateAssetGroupRequest{Name: "test", Tag: "test"})
if role.Permissions.Has(auth.Permissions().GraphDBWrite) {
assert.Nil(err)
} else {
requireForbidden(assert, err)
}
}),

lab.TestCase(fmt.Sprintf("%s be able to access GraphDBIngest endpoints", testCondition(role, auth.Permissions().GraphDBIngest)), func(assert *require.Assertions, harness *lab.Harness) {
userClient, ok := lab.Unpack(harness, userClientFixture)
assert.True(ok)

_, err := userClient.CreateFileUploadTask()
if role.Permissions.Has(auth.Permissions().GraphDBIngest) {
assert.Nil(err)
} else {
requireForbidden(assert, err)
}
}),

lab.TestCase(fmt.Sprintf("%s be able to access GraphDBRead endpoints", testCondition(role, auth.Permissions().GraphDBRead)), func(assert *require.Assertions, harness *lab.Harness) {
userClient, ok := lab.Unpack(harness, userClientFixture)
assert.True(ok)
Expand Down
2 changes: 1 addition & 1 deletion cmd/api/src/database/analysisrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (s *BloodhoundDB) setAnalysisRequest(ctx context.Context, requestType model
} else {
// Analysis request existed, we only want to overwrite if request is for a deletion request, otherwise ignore additional requests
if analReq.RequestType == model.AnalysisRequestAnalysis && requestType == model.AnalysisRequestDeletion {
updateSql := `update analysis_request_switch set requested_by = ?, request_type = ?, requested_at = ? limit 1;`
updateSql := `update analysis_request_switch set requested_by = ?, request_type = ?, requested_at = ?;`
tx := s.db.WithContext(ctx).Exec(updateSql, requestedBy, requestType, time.Now().UTC())
return tx.Error
}
Expand Down
51 changes: 51 additions & 0 deletions cmd/api/src/database/migration/migrations/v6.2.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
-- Copyright 2024 Specter Ops, Inc.
--
-- Licensed under the Apache License, Version 2.0
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- SPDX-License-Identifier: Apache-2.0

-- Add updated posture page feature flag
INSERT INTO feature_flags (created_at, updated_at, key, name, description, enabled, user_updatable)
VALUES (current_timestamp,
current_timestamp,
'updated_posture_page',
'Updated Posture Page',
'Enables the updated version of the posture page in the UI application',
false,
false)
ON CONFLICT DO NOTHING;

INSERT INTO permissions (authority, name, created_at, updated_at) VALUES ('graphdb', 'Ingest', current_timestamp, current_timestamp) ON CONFLICT DO NOTHING;

-- Grant the Upload-Only user GraphDBIngest permissions
INSERT INTO roles_permissions (role_id, permission_id)
VALUES ((SELECT id FROM roles WHERE roles.name = 'Upload-Only'),
(SELECT id FROM permissions WHERE permissions.authority = 'graphdb' and permissions.name = 'Ingest'))
ON CONFLICT DO NOTHING;

-- Grant the Power User user GraphDBIngest permissions
INSERT INTO roles_permissions (role_id, permission_id)
VALUES ((SELECT id FROM roles WHERE roles.name = 'Power User'),
(SELECT id FROM permissions WHERE permissions.authority = 'graphdb' and permissions.name = 'Ingest'))
ON CONFLICT DO NOTHING;

-- Grant the Admininstrator user GraphDBIngest permissions
INSERT INTO roles_permissions (role_id, permission_id)
VALUES ((SELECT id FROM roles WHERE roles.name = 'Administrator'),
(SELECT id FROM permissions WHERE permissions.authority = 'graphdb' and permissions.name = 'Ingest'))
ON CONFLICT DO NOTHING;

-- Remove the GraphDBWrite permission from the Upload-Only role
DELETE FROM roles_permissions
WHERE role_id = (SELECT id FROM roles WHERE roles.name = 'Upload-Only')
AND permission_id = (SELECT id FROM permissions WHERE permissions.authority = 'graphdb' AND permissions.name = 'Write');
1 change: 1 addition & 0 deletions cmd/api/src/model/appcfg/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const (
FeatureDarkMode = "dark_mode"
FeatureAutoTagT0ParentObjects = "auto_tag_t0_parent_objects"
FeatureOIDCSupport = "oidc_support"
FeatureUpdatedPosturePage = "updated_posture_page"
)

// FeatureFlag defines the most basic details of what a feature flag must contain to be actionable. Feature flags should be
Expand Down
88 changes: 87 additions & 1 deletion docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ services:
- ui-only
- debug-api
- pg-only
- sso
image: docker.io/library/postgres:16
environment:
- PGUSER=${BH_POSTGRES_USER:-bloodhound}
Expand Down Expand Up @@ -62,6 +63,7 @@ services:
- ui-only
- debug-api
- pg-only
- sso
build:
context: tools/docker-compose
dockerfile: pgadmin.Dockerfile
Expand All @@ -86,6 +88,7 @@ services:
- api-only
- ui-only
- debug-api
- sso
build:
args:
memconfig: true
Expand All @@ -112,7 +115,7 @@ services:
retries: 5
start_period: 30s

bh-api:
bh-api: &bh-api
profiles:
- dev
- api-only
Expand Down Expand Up @@ -143,6 +146,7 @@ services:
- dev
- ui-only
- debug-api
- sso
build:
context: .
dockerfile: tools/docker-compose/ui.Dockerfile
Expand Down Expand Up @@ -185,8 +189,90 @@ services:
graph-db:
condition: service_healthy

bh-api-sso:
<<: *bh-api
profiles:
- sso
links:
- authentik:authentik.localhost

authentik:
profiles:
- sso
- sso-only
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7}
restart: unless-stopped
command: server
environment:
AUTHENTIK_REDIS__HOST: authentik-valkey
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: ${ATK_BH_PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${ATK_BH_PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${ATK_BH_PG_PASS:-bloodhoundcommunityedition}
AUTHENTIK_SECRET_KEY: ${ATK_BH_SECRET:-bloodhoundcommunityedition}
labels:
- traefik.enable=true
- traefik.http.routers.authentik.rule=Host(`${BH_AUTHENTIK_HOSTNAME:-authentik.localhost}`)
- traefik.http.routers.authentik.service=authentik
- traefik.http.services.authentik.loadbalancer.server.port=9000
ports:
- "${COMPOSE_PORT_HTTP:-9000}:9000"
- "${COMPOSE_PORT_HTTPS:-9443}:9443"
depends_on:
- authentik-db
- authentik-valkey

authentik-worker:
profiles:
- sso
- sso-only
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.7}
restart: unless-stopped
command: worker
environment:
AUTHENTIK_REDIS__HOST: authentik-valkey
AUTHENTIK_POSTGRESQL__HOST: authentik-db
AUTHENTIK_POSTGRESQL__USER: ${ATK_BH_PG_USER:-authentik}
AUTHENTIK_POSTGRESQL__NAME: ${ATK_BH_PG_DB:-authentik}
AUTHENTIK_POSTGRESQL__PASSWORD: ${ATK_BH_PG_PASS:-bloodhoundcommunityedition}
AUTHENTIK_SECRET_KEY: ${ATK_BH_SECRET:-bloodhoundcommunityedition}
depends_on:
- authentik-db
- authentik-valkey

authentik-valkey:
profiles:
- sso
- sso-only
image: docker.io/valkey/valkey:alpine
command: --save 60 1 --loglevel warning
restart: unless-stopped
volumes:
- authentik-valkey:/data

authentik-db:
profiles:
- sso
- sso-only
image: docker.io/library/postgres:13.2-alpine
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- authentik-db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${ATK_BH_PG_PASS:-bloodhoundcommunityedition}
POSTGRES_USER: ${ATK_BH_PG_USER:-authentik}
POSTGRES_DB: ${ATK_BH_PG_DB:-authentik}

volumes:
neo4j-data:
postgres-data:
go-pkg-mod:
ui-cache:
authentik-valkey:
authentik-db:
4 changes: 2 additions & 2 deletions examples/docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
test:
[
"CMD-SHELL",
"pg_isready -U ${POSTGRES_USER:-bloodhound} -d ${POSTGRES_DB:-bloodhound} -h 127.0.0.1 -p ${POSTGRES_PORT:-5432}"
"pg_isready -U ${POSTGRES_USER:-bloodhound} -d ${POSTGRES_DB:-bloodhound} -h 127.0.0.1 -p 5432"
]
interval: 10s
timeout: 5s
Expand All @@ -53,7 +53,7 @@ services:
test:
[
"CMD-SHELL",
"wget -O /dev/null -q http://localhost:${NEO4J_WEB_PORT:-7474} || exit 1"
"wget -O /dev/null -q http://localhost:7474 || exit 1"
]
interval: 10s
timeout: 5s
Expand Down
8 changes: 8 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ bh-ui-only *ARGS='up':
pg-only *ARGS='up':
@docker compose --profile pg-only -f docker-compose.dev.yml {{ARGS}}

# run docker compose commands for the BH dev profile with SSO IDP Authentik (Default: up)
bh-sso *ARGS='up':
@docker compose --profile sso -f docker-compose.dev.yml {{ARGS}}

# run docker compose commands for the SSO IDP Authentik only (Default: up)
bh-sso-only *ARGS='up':
@docker compose --profile sso-only -f docker-compose.dev.yml {{ARGS}}

# run docker compose commands for the BH testing databases (Default: up)
bh-testing *ARGS='up -d':
@docker compose --project-name bh-testing -f docker-compose.testing.yml {{ARGS}}
Expand Down

0 comments on commit 923a124

Please sign in to comment.