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
34 changes: 34 additions & 0 deletions cmd/secops-chaos-ai/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: end-of-file-fixer
types: [ python ]
- id: requirements-txt-fixer

- repo: https://github.com/psf/black
rev: 23.7.0
hooks:
- id: black
args: [ --line-length=100, --exclude="" ]

# this is not technically always safe but usually is
# use comments `# isort: off` and `# isort: on` to disable/re-enable isort
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: [ --line-length=100, --profile=black ]

- repo: https://github.com/zricethezav/gitleaks
rev: v8.17.0
hooks:
- id: gitleaks

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.35.0
hooks:
- id: markdownlint
37 changes: 37 additions & 0 deletions cmd/secops-chaos-ai/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
FROM python:3.11-slim

LABEL org.opencontainers.image.source=https://github.com/OperantAI/secops-chaos
LABEL org.opencontainers.image.description="AI Security focused Chaos Experiments"

# Install system packages needed for building
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
&& apt-get clean && rm -rf /var/lib/apt/lists/*

RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH

# ensures that the python output is sent straight to terminal (e.g. your container log)
ENV PYTHONUNBUFFERED 1

# https://docs.python.org/3/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE
ENV PYTHONDONTWRITEBYTECODE 1

WORKDIR $HOME/app

COPY --chown=user:user ./cmd/secops-chaos-ai/pyproject.toml ./
COPY --chown=user:user ./cmd/secops-chaos-ai/app ./app


RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir .

COPY --chown=user:user ./cmd/secops-chaos-ai/entrypoint.sh ./

RUN chmod +x /home/user/app/entrypoint.sh

EXPOSE 8000

CMD ["/home/user/app/entrypoint.sh"]
36 changes: 36 additions & 0 deletions cmd/secops-chaos-ai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Secops Chaos for AI

Secops Chaos component for running security-focused chaos experiments
against AI apps and APIs

## Pre-commit

```sh
pip3 install pre-commit
pre-commit run --files ./*
````

## Build

```sh
pip3 install .
```

## Running

```sh
export OPENAI_API_KEY="my-api-key"
./entrypoint.sh
````

## Docker Build

```sh
docker build -t secops-chaos-ai:latest . -f Dockerfile
````

## Docker Run

```sh
docker run -p 8000:8000 -e OPENAI_API_KEY=<> secops-chaos-ai:latest
````
Empty file.
28 changes: 28 additions & 0 deletions cmd/secops-chaos-ai/app/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import argparse

import uvicorn

from .app import create_app


def run_uvicorn():
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, help="Port to run the server on", default=8000)
args = parser.parse_args()

uvicorn.run(
create_app(),
host="0.0.0.0",
port=args.port,
server_header=False,
proxy_headers=True,
forwarded_allow_ips="*",
timeout_keep_alive=2,
)


if __name__ == "__main__":
parser = argparse.ArgumentParser()
args = parser.parse_args()

run_uvicorn()
79 changes: 79 additions & 0 deletions cmd/secops-chaos-ai/app/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from openai import OpenAI
from typing import List
from pydantic import BaseModel
import os

def create_app() -> FastAPI:

app = FastAPI(
title="Secops Chaos AI API",
)

register_routes(app)

return app

client = OpenAI(
api_key=os.getenv("OPENAI_KEY")
)

def register_routes(
app: FastAPI,
):
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["Authorization", "Content-Type"],
)
@app.get("/")
async def root():
return {"message": "Hello World"}

class AIExperimentVerifierResponse(BaseModel):
check: str
detected: bool
score: float

class AIExperiment(BaseModel):
model: str
ai_api: str
system_prompt: str
prompt: str
verify_prompt_checks: List[str]
verify_response_checks: List[str]

class AIExperimentResponse(BaseModel):
model: str
ai_api: str
prompt: str
api_response: str
verified_prompt_checks: List[AIExperimentVerifierResponse]
verified_response_checks: List[AIExperimentVerifierResponse]


@app.post("/ai-experiments")
async def chat(experiment: AIExperiment):
match experiment.model:
case "gpt-4o":
completion = client.chat.completions.create(
model="gpt-4o",
messages = [
experiment.system_prompt,
{"role": "user", "content": experiment.prompt}
]
)
verified_prompt_checks = list()
verified_response_checks = list()
for check in experiment.verify_prompt_checks:
verified_prompt_checks.append(AIExperimentVerifierResponse(check=check, detected=bool(False), score=0.0)) #TODO plug-in checkers

for check in experiment.verify_response_checks:
verified_response_checks.append(AIExperimentVerifierResponse(check=check, detected=bool(False), score=0.0)) #TODO plug-in checkers

return AIExperimentResponse(model=experiment.model, ai_api=experiment.ai_api, prompt=experiment.prompt,
api_response=completion.choices[0].message.content, verified_prompt_checks=verified_prompt_checks,
verified_response_checks=verified_response_checks)
3 changes: 3 additions & 0 deletions cmd/secops-chaos-ai/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

secops-chaos-ai-api
27 changes: 27 additions & 0 deletions cmd/secops-chaos-ai/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[project]
name = "secops-chaos-ai"
authors = [
{ name = "Glenn McDonald", email = "glenn.mcdonald@operant.ai" },
{ name = "Priyanka Tembey", email = "priyanka@operant.ai"}
]
version = "0.0.1"
readme = "README.md"
requires-python = ">=3.11"

dependencies = [
"asyncio==3.4.3",
"fastapi>=0.110",
"pydantic==1.10.14",
"openai==1.30.5",
"uvicorn[standard]>=0.29",
]

[tool.setuptools]
packages = ["app"]

[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"

[project.scripts]
secops-chaos-ai-api = "app.__main__:run_uvicorn"