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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 47 additions & 13 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@ pipeline {
choice(
name: 'ATTACK_MODE',
choices: [
'ALL_SEQUENTIAL',
'NONE',
'POISONING',
'STEALTHY',
'SYBIL_SIMULATION',
'GRADIENT_INVERSION'
],
description: 'Attack scenario to test',
'ALL_SEQUENTIAL',
'NONE',
'POISONING',
'MODEL_POISONING',
'DATA_POISONING',
'BACKDOOR',
'LABEL_FLIP',
'STEALTHY',
'SYBIL_SIMULATION',
'GRADIENT_INVERSION',
'MEMBERSHIP_INFERENCE',
'PROPERTY_INFERENCE',
'MODEL_REPLACEMENT',
'MALICIOUS_AGGREGATION',
'ADVERSARIAL_EXAMPLES',
'MODEL_DRIFT',
'FREE_RIDING',
'SIGN_FLIP',
'GAUSSIAN_NOISE'
],
description: 'Attack scenario to test'
)

string(
Expand Down Expand Up @@ -132,7 +145,7 @@ pipeline {
exit 0
fi
echo "Waiting for server... ($i/12)"
sleep 5
sleep 15
done
echo "Server failed to start"
exit 1
Expand All @@ -151,7 +164,25 @@ pipeline {

if (params.ATTACK_MODE == 'ALL_SEQUENTIAL') {
// Iterate through all actual attack types
def attacks = ['POISONING', 'STEALTHY', 'SYBIL_SIMULATION', 'GRADIENT_INVERSION']
def attacks = [
'POISONING',
'MODEL_POISONING',
'DATA_POISONING',
'BACKDOOR',
'LABEL_FLIP',
'STEALTHY',
'SYBIL_SIMULATION',
'GRADIENT_INVERSION',
'MEMBERSHIP_INFERENCE',
'PROPERTY_INFERENCE',
'MODEL_REPLACEMENT',
'MALICIOUS_AGGREGATION',
'ADVERSARIAL_EXAMPLES',
'MODEL_DRIFT',
'FREE_RIDING',
'SIGN_FLIP',
'GAUSSIAN_NOISE'
];
for (attack in attacks) {
runAttackScenario(attack)
}
Expand Down Expand Up @@ -265,12 +296,15 @@ def runAttackScenario(String attackMode) {
# 1. Update the attack mode in the compose file
sed -i.bak "s/ATTACK_MODE=.*/ATTACK_MODE=${attackMode}/" infra/docker/docker-compose-app.yml

# 2. Recreate ONLY the malicious client.
# 2. Force clean malicious client for a new attack
docker rm -f fl_malicious_client || true

# 3. Recreate ONLY the malicious client.
docker compose -f infra/docker/docker-compose-app.yml up -d --no-deps --force-recreate malicious_client

sleep 5
sleep 20

# 4. FIX: Use ${params.FL_ROUNDS} so Jenkins actually passes the value
# 4. Trigger training
docker exec fl_server python3 utils/control.py --mode train --rounds ${params.FL_ROUNDS} --wait ${params.FL_WAIT}

echo " Attack scenario ${attackMode} completed"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,75 +1,75 @@
apiVersion: 1
# apiVersion: 1

groups:
- orgId: 1
name: 'FL-Security-Alerts'
folder: 'Federated Learning'
interval: 10s
rules:
- uid: 'alert-attack-detected'
title: 'Active Attack Detected'
condition: 'B'
data:
- refId: 'A'
relativeTimeRange:
from: 300
to: 0
datasourceUid: 'P8E80F9AEF21F6940'
model:
expr: 'count_over_time({job="fl_server"} | json | event_type="ATTACK_DETECTED" [1m])'
refId: 'A'
- refId: 'B'
datasourceUid: '__expr__'
model:
conditions: [ { evaluator: { params: [ 0 ], type: 'gt' }, operator: { type: 'and' }, query: { params: [ 'A' ] }, reducer: { params: [], type: 'sum' }, type: 'query' } ]
datasource: { type: '__expr__', uid: '__expr__' }
expression: 'A'
type: 'threshold'
noDataState: 'OK'
for: 0s
annotations:
summary: 'Attack detected on FL Server'
description: 'The security module detected a malicious update attempting to poison the model.'
labels:
severity: 'critical'
category: 'security'
# groups:
# - orgId: 1
# name: 'FL-Security-Alerts'
# folder: 'Federated Learning'
# interval: 10s
# rules:
# - uid: 'alert-attack-detected'
# title: 'Active Attack Detected'
# condition: 'B'
# data:
# - refId: 'A'
# relativeTimeRange:
# from: 300
# to: 0
# datasourceUid: 'P8E80F9AEF21F6940'
# model:
# expr: 'count_over_time({job="fl_server"} | json | event_type="ATTACK_DETECTED" [1m])'
# refId: 'A'
# - refId: 'B'
# datasourceUid: '__expr__'
# model:
# conditions: [ { evaluator: { params: [ 0 ], type: 'gt' }, operator: { type: 'and' }, query: { params: [ 'A' ] }, reducer: { params: [], type: 'sum' }, type: 'query' } ]
# datasource: { type: '__expr__', uid: '__expr__' }
# expression: 'A'
# type: 'threshold'
# noDataState: 'OK'
# for: 0s
# annotations:
# summary: 'Attack detected on FL Server'
# description: 'The security module detected a malicious update attempting to poison the model.'
# labels:
# severity: 'critical'
# category: 'security'

- uid: 'alert-sast-critical'
title: '☣️ Critical Vulnerability in Code'
condition: 'B'
data:
- refId: 'A'
datasourceUid: 'PBFA97CFB590B2093'
model:
expr: 'sast_bandit_issues_high'
refId: 'A'
- refId: 'B'
datasourceUid: '__expr__'
model:
conditions: [ { evaluator: { params: [ 0 ], type: 'gt' }, operator: { type: 'and' }, query: { params: [ 'A' ] }, reducer: { params: [], type: 'last' }, type: 'query' } ]
datasource: { type: '__expr__', uid: '__expr__' }
expression: 'A'
type: 'threshold'
noDataState: 'OK'
for: 1m
annotations:
summary: 'Critical SAST Issue Found'
description: 'Bandit scan found high-severity vulnerabilities in the production code.'
labels:
severity: 'warning'
category: 'code-quality'
# - uid: 'alert-sast-critical'
# title: '☣️ Critical Vulnerability in Code'
# condition: 'B'
# data:
# - refId: 'A'
# datasourceUid: 'PBFA97CFB590B2093'
# model:
# expr: 'sast_bandit_issues_high'
# refId: 'A'
# - refId: 'B'
# datasourceUid: '__expr__'
# model:
# conditions: [ { evaluator: { params: [ 0 ], type: 'gt' }, operator: { type: 'and' }, query: { params: [ 'A' ] }, reducer: { params: [], type: 'last' }, type: 'query' } ]
# datasource: { type: '__expr__', uid: '__expr__' }
# expression: 'A'
# type: 'threshold'
# noDataState: 'OK'
# for: 1m
# annotations:
# summary: 'Critical SAST Issue Found'
# description: 'Bandit scan found high-severity vulnerabilities in the production code.'
# labels:
# severity: 'warning'
# category: 'code-quality'

contactPoints:
- orgId: 1
name: 'Critical-Channel'
receivers:
- uid: 'email-receiver'
type: email
settings:
addresses: 'admin@example.com'
singleEmail: true
# contactPoints:
# - orgId: 1
# name: 'Critical-Channel'
# receivers:
# - uid: 'email-receiver'
# type: email
# settings:
# addresses: 'admin@example.com'
# singleEmail: true

policies:
- orgId: 1
receiver: 'Critical-Channel'
group_by: ['alertname']
# policies:
# - orgId: 1
# receiver: 'Critical-Channel'
# group_by: ['alertname']
Loading