-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6d703b1
Showing
24 changed files
with
1,590 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
__pycache__ | ||
logs | ||
creds.json/* | ||
logs.zip | ||
temp/ | ||
temp.txt | ||
env/ | ||
actionPolicies/ | ||
actionsUsers/ | ||
crudActions/ | ||
finalUserPolicies/ | ||
userPolicies*/ | ||
presentPolicies*/ | ||
logs*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM python:3.9-alpine | ||
|
||
RUN apk add --no-cache python3-dev gcc musl-dev libffi-dev libpq-dev openssl-dev make && \ | ||
apk add --no-cache redis | ||
|
||
WORKDIR /app | ||
COPY requirements.txt ./ | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
COPY . . | ||
EXPOSE 8000 | ||
CMD ["sh", "-c", "redis-server & uvicorn app:app --reload --host 0.0.0.0"] | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
![CloudDefence](assets/banner.png) | ||
|
||
## AWS Zero Trust policy by CloudDefenseAI | ||
|
||
The AWS Policy Generator API is a FastAPI application that helps you generate AWS IAM policies based on AWS CloudTrail logs. The API accepts a JSON payload containing the required AWS credentials, regions, and other relevant information, and then runs the policy generation process. Upon successful completion, it returns the time taken to generate the policies. | ||
|
||
![data flow](assets/Data_Flow.jpg) | ||
|
||
## Prerequisites | ||
|
||
Before you begin, make sure you have the following prerequisites in place: | ||
|
||
To run the AWS Policy Generator API, you need: | ||
|
||
1. Python 3.6 or higher | ||
2. FastAPI and Uvicorn packages installed | ||
3. redis server | ||
|
||
## Installation | ||
|
||
To install and use the extended rule set for Falco runtime security, follow these steps: | ||
|
||
1. Clone the Repository: Start by cloning this GitHub repository to your local system: | ||
|
||
``` | ||
git clone https://github.com/CloudDefenseAI/AWSZeroTrustPolicy | ||
``` | ||
|
||
2. Navigate to the Repository: Change to the repository directory: | ||
|
||
``` | ||
cd AWSZeroTrustPolicy | ||
``` | ||
|
||
3. install python libraries | ||
|
||
``` | ||
pip install -r requirements.txt | ||
``` | ||
|
||
## Usage | ||
|
||
1. Run Redis server | ||
`redis-server` | ||
|
||
2. Run the uvicorn application | ||
`uvicorn app:app --reload --host 0.0.0.0 --log-level debug` | ||
|
||
3. Send the following curl request to generate the zerotrust policy | ||
|
||
``` | ||
curl -X POST -H "Content-Type: application/json" -d '{ | ||
"accountType": "Credential", | ||
"accessKey": "accessKey", | ||
"secretKey": "secretKey", | ||
"externalId": "externalId", | ||
"roleArn": "roleArn", | ||
"accountId": "accountId", | ||
"days": 30, | ||
"bucketData": { | ||
"us-east-1": "aws-cloudtrail-logs-407638845061-1f72c339" | ||
} | ||
}' http://localhost:8000/run | ||
``` | ||
|
||
## Contributing | ||
|
||
If you want to help and wish to contribute, please review our contribution guidelines. Code contributions are always encouraged and welcome! | ||
|
||
## License | ||
|
||
This extended rule set for Falco runtime security is released under the [Apache-2.0 License](url). | ||
|
||
## Disclaimer: | ||
|
||
The content and code available in this GitHub repository are currently a work in progress. Please note that the rules, guidelines, or any other materials provided here are subject to change without prior notice. | ||
While we aim to ensure the accuracy and completeness of the information presented, there may be errors or omissions. We kindly request users to exercise caution and critical judgment when utilizing or relying on any content found in this repository. | ||
We appreciate your understanding and patience as we continue to develop and refine the content within this repository. Contributions, feedback, and suggestions are welcome and greatly valued, as they contribute to the ongoing improvement of this project. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import json | ||
from fastapi import FastAPI, HTTPException, Depends, Request | ||
from fastapi.middleware.cors import CORSMiddleware | ||
from schemas import Script | ||
from runner import runner | ||
from datetime import datetime | ||
|
||
app = FastAPI() | ||
|
||
@app.post("/run") | ||
def run_script(script: Script): | ||
print(f"Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") | ||
print("Payload:") | ||
print(json.dumps(script.dict(), indent=4)) | ||
|
||
try: | ||
resp = runner(script.accountType, script.accessKey, script.secretKey, script.accountId, script.days | ||
, script.bucketData, script.roleArn, script.externalId) | ||
except Exception as e: | ||
raise HTTPException(status_code=500, detail=str(e)) | ||
|
||
return {"accountId": resp['accountId'], "generatedPolicies": resp['generatedPolicies'], "consolidatedPolicies": resp['consolidatedPolicies'], "excessivePolicies": resp['excessivePolicies']} | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import json | ||
import boto3 | ||
from botocore.credentials import Credentials | ||
from botocore.exceptions import ClientError, NoCredentialsError, BotoCoreError | ||
from fastapi import HTTPException | ||
|
||
class AWSOperations: | ||
def connect_to_iam_with_assumed_role(self, aws_credentials): | ||
# Create a new session with the temporary credentials | ||
session = boto3.Session( | ||
aws_access_key_id=aws_credentials.access_key, | ||
aws_secret_access_key=aws_credentials.secret_key, | ||
aws_session_token=aws_credentials.token | ||
) | ||
# Use the new session to connect to IAM | ||
iam_client = session.client('iam') | ||
return iam_client | ||
|
||
def get_iam_connection(self): | ||
try: | ||
with open("config.json", "r") as f: | ||
data = json.loads(f.read()) | ||
if data['accountType'] == "CloudFormation": | ||
aws_credentials = self.get_assume_role_credentials(data) | ||
iam_client = self.connect_to_iam_with_assumed_role(aws_credentials) | ||
elif data['accountType'] == "Credential": | ||
iam_client = self.connect("iam", data['aws_access_key_id'], data['aws_secret_access_key']) | ||
return iam_client | ||
except (FileNotFoundError, json.JSONDecodeError) as e: | ||
raise HTTPException(status_code=500, detail=f"Error reading or parsing config.json: {e}") | ||
|
||
except (ClientError, NoCredentialsError, BotoCoreError) as e: | ||
raise HTTPException(status_code=500, detail=f"Error connecting to IAM: {e}") | ||
|
||
|
||
def connect(self,serviceName,aws_access_key_id,aws_secret_access_key): | ||
s3Client = boto3.client(serviceName,aws_access_key_id=aws_access_key_id,aws_secret_access_key=aws_secret_access_key) | ||
return s3Client | ||
|
||
def connect_to_s3_with_assumed_role(self,aws_credentials): | ||
# Create a new session with the temporary credentials | ||
session = boto3.Session( | ||
aws_access_key_id=aws_credentials.access_key, | ||
aws_secret_access_key=aws_credentials.secret_key, | ||
aws_session_token=aws_credentials.token | ||
) | ||
# Use the new session to connect to S3 | ||
s3_client = session.client('s3') | ||
return s3_client | ||
|
||
def getConnection(self): | ||
try: | ||
with open("config.json", "r") as f: | ||
data = json.loads(f.read()) | ||
if data['accountType'] == "CloudFormation": | ||
aws_credentials = self.get_assume_role_credentials(data) | ||
s3_client = self.connect_to_s3_with_assumed_role(aws_credentials) | ||
elif data['accountType'] == "Credential": | ||
s3_client = self.connect("s3", data['aws_access_key_id'], data['aws_secret_access_key']) | ||
return s3_client | ||
except (FileNotFoundError, json.JSONDecodeError) as e: | ||
raise HTTPException(status_code=500, detail=f"Error reading or parsing config.json: {e}") | ||
except (ClientError, NoCredentialsError, BotoCoreError) as e: | ||
raise HTTPException(status_code=500, detail=f"Error connecting to S3: {e}") | ||
|
||
def get_assume_role_credentials(self, account): | ||
try: | ||
# Create an STS client with the IAM user's access and secret keys | ||
sts_client = boto3.client( | ||
'sts', | ||
aws_access_key_id=account['aws_access_key_id'], | ||
aws_secret_access_key=account['aws_secret_access_key'] | ||
) | ||
|
||
# Assume the IAM role | ||
response = sts_client.assume_role( | ||
RoleArn=account['role_arn'], | ||
RoleSessionName='Assume_Role_Session', | ||
DurationSeconds=43200, | ||
ExternalId=account['externalid'] | ||
) | ||
|
||
# Extract the temporary credentials | ||
creds = response['Credentials'] | ||
session_credentials = boto3.Session( | ||
aws_access_key_id=creds['AccessKeyId'], | ||
aws_secret_access_key=creds['SecretAccessKey'], | ||
aws_session_token=creds['SessionToken'] | ||
).get_credentials() | ||
|
||
# Create an AwsCredentials object with the temporary credentials | ||
aws_credentials = Credentials( | ||
access_key=session_credentials.access_key, | ||
secret_key=session_credentials.secret_key, | ||
token=session_credentials.token | ||
) | ||
|
||
return aws_credentials | ||
|
||
except (ClientError, NoCredentialsError, BotoCoreError) as e: | ||
raise HTTPException(status_code=500, detail=f"Error assuming role: {e}") | ||
|
||
|
Oops, something went wrong.