Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: audit mode #278

Merged
merged 1 commit into from
Jun 13, 2024
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
1 change: 1 addition & 0 deletions .github/workflows/.reusable-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:
"basic",
"autofix",
"semgrep_login",
"audit",
]
steps:
- name: Checkout code
Expand Down
2 changes: 1 addition & 1 deletion charts/semgr8s/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@ Create the name of the environments to use

{{- define "semgr8s.getFileName" -}}
{{- . | trimPrefix "rules/" | replace "/" "_" }}
{{- end }}
{{- end }}
5 changes: 3 additions & 2 deletions charts/semgr8s/templates/env.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ metadata:
labels:
{{- include "semgr8s.labels" . | nindent 4 }}
data:
SEMGREP_RULES: {{ join " " .Values.application.remoteRules | quote }}
NAMESPACE: {{ .Release.Namespace }}
ENFORCE: {{ .Values.application.enforce | quote }}
SEMGREP_RULES: {{ join " " .Values.application.remoteRules | quote }}
NAMESPACE: {{ .Release.Namespace }}
5 changes: 3 additions & 2 deletions charts/semgr8s/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ webhooks: # configuration options for webhooks described under https://kubernet
operations: ["CREATE", "UPDATE"]

application:
# Apply remote rules from e.g.
enforce: true # fail on rule violation (true/false)
# remoteRules: Apply remote rules from e.g.
# * semgrep registry: https://semgrep.dev/r
# * semgrep-rules github repo: https://github.com/semgrep/semgrep-rules
# common choices: p/kubernetes, r/yaml.kubernetes
remoteRules: ["p/kubernetes"]
autofix: false
autofix: false # apply semgrep fixes before validation (see https://semgrep.dev/docs/writing-rules/autofix)
semgrepLogin: false # requires generic secret with name 'semgrep-app-token' and key 'token' in semgr8ns namespace
8 changes: 8 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,14 @@ kubectl delete -f tests/demo/

## Features

### Audit mode

It is possible to run Semgr8s in *audit* mode by which it will not block but only warn on non-compliant resources.
As the logs contain an explicit error code, it is possible to alert on admission responses with warnings via typical monitoring solutions such as [Prometheus](https://prometheus.io/) or [DataDog](https://www.datadoghq.com/).
This is particularly useful during rollout of Semgr8s and for enforcement of new policies.

To activate audit mode, set `.application.enforce=false` in the `charts/semgr8s/values.yaml`.

### Semgrep login

With the *Semgrep login* feature, you can connect Semgr8s to your [Semgrep AppSec Platform](https://semgrep.dev/login) account and use platform features such as [private remote rules](https://semgrep.dev/docs/writing-rules/private-rules).
Expand Down
19 changes: 12 additions & 7 deletions semgr8s/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from semgr8s.files import S8sFiles

APP = Flask(__name__)
AUDIT = os.environ.get("ENFORCE", "true").lower() == "false"


@APP.route("/health", methods=["GET", "POST"])
Expand Down Expand Up @@ -70,7 +71,7 @@ def perform_review(
'allowed': <bool True/False>,
'status': {
'code': <int http_status_codes>,
'message': <str reponse_message>
'msg': <str reponse_msg>
},
'uid': <str admission_request_uid>
}
Expand Down Expand Up @@ -181,26 +182,30 @@ def perform_review(
return send_response(True, uid, 201, "Compliant resource admitted")


def send_response(allowed, uid, code, message, patch=None):
def send_response(allowed, uid, code, msg, patch=None):
"""
Prepare json response in expected format based on validation result.
"""
APP.logger.info(
"> response:(allowed=%s, uid=%s, status_code=%s message=%s)",
allowed,
"> response:(allowed=%s, uid=%s, status_code=%s msg=%s)",
allowed | AUDIT,
uid,
code,
message,
msg,
)
review = {
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"allowed": allowed,
"allowed": allowed | AUDIT,
"uid": uid,
"status": {"code": code, "message": message},
"status": {"code": code, "message": msg},
},
}

if AUDIT and not allowed:
review["response"]["warnings"] = ["[Semgr8s] " + msg.replace("\n", "")]

if patch:
review["response"]["patchType"] = "JSONPatch"
review["response"]["patch"] = base64.b64encode(
Expand Down
5 changes: 5 additions & 0 deletions tests/integration/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ source "${SCRIPT_PATH}/scripts/basic.sh"
source "${SCRIPT_PATH}/scripts/remote_rules.sh"
source "${SCRIPT_PATH}/scripts/autofix.sh"
source "${SCRIPT_PATH}/scripts/semgrep_login.sh"
source "${SCRIPT_PATH}/scripts/audit.sh"

# backup values.yaml
cp charts/semgr8s/values.yaml charts/semgr8s/values.yaml.bak
Expand All @@ -40,6 +41,10 @@ case $1 in
# testing semgrep appsec platform login with private rules
semgrep_login_integration_test
;;
"audit")
# testing autofixing with mutating webhook
audit_integration_test
;;
"restore")
restore
;;
Expand Down
10 changes: 10 additions & 0 deletions tests/integration/scripts/audit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
set -euo pipefail

audit_integration_test() {
create_test_namespaces
update_with_file "audit"
install "make"
multi_test "audit"
uninstall "make"
}
27 changes: 27 additions & 0 deletions tests/integration/test_cases/audit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
testCases:
- id: a-01
txt: Testing compliant pod...
type: k8s-yaml
ref: 20_compliant_pod
namespace: validatedns
expected_msg: pod/compliant-pod created
- id: a-02
txt: Testing non-compliant pod against local rule for forbidden test label...
type: k8s-yaml
ref: 40_testlabel_pod
namespace: validatedns
expected_msg: "Warning: [Semgr8s] Found 1 violation"
- id: a-03
txt: Testing non-compliant pod against local rule for forbidden test label...
type: k8s-yaml
ref: 41_nosc_pod
namespace: validatedns
expected_msg: pod/nosc-pod created

values:
deployment:
image:
repository: "${IMAGE}"
tag: "${TAG}"
application:
enforce: false
Loading