forked from phoenix/litellm-mirror
Resolve merge conflicts
This commit is contained in:
commit
632b7ce17d
167 changed files with 6479 additions and 538 deletions
|
@ -50,7 +50,7 @@ Use `litellm.get_supported_openai_params()` for an updated list of params for ea
|
|||
|Huggingface| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | |
|
||||
|Openrouter| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | | | ✅ | | | | |
|
||||
|AI21| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | |
|
||||
|VertexAI| ✅ | ✅ | | ✅ | ✅ | | | | | | | | | | ✅ | | |
|
||||
|VertexAI| ✅ | ✅ | | ✅ | ✅ | | | | | | | | | ✅ | ✅ | | |
|
||||
|Bedrock| ✅ | ✅ | ✅ | ✅ | ✅ | | | | | | | | | | ✅ (for anthropic) | |
|
||||
|Sagemaker| ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | | |
|
||||
|TogetherAI| ✅ | ✅ | ✅ | ✅ | ✅ | | | | | | ✅ |
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
# Completion Token Usage & Cost
|
||||
By default LiteLLM returns token usage in all completion requests ([See here](https://litellm.readthedocs.io/en/latest/output/))
|
||||
|
||||
However, we also expose some helper functions + **[NEW]** an API to calculate token usage across providers:
|
||||
LiteLLM returns `response_cost` in all calls.
|
||||
|
||||
```python
|
||||
from litellm import completion
|
||||
|
||||
response = litellm.completion(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=[{"role": "user", "content": "Hey, how's it going?"}],
|
||||
mock_response="Hello world",
|
||||
)
|
||||
|
||||
print(response._hidden_params["response_cost"])
|
||||
```
|
||||
|
||||
LiteLLM also exposes some helper functions:
|
||||
|
||||
- `encode`: This encodes the text passed in, using the model-specific tokenizer. [**Jump to code**](#1-encode)
|
||||
|
||||
|
@ -23,7 +37,7 @@ However, we also expose some helper functions + **[NEW]** an API to calculate to
|
|||
|
||||
- `api.litellm.ai`: Live token + price count across [all supported models](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json). [**Jump to code**](#10-apilitellmai)
|
||||
|
||||
📣 This is a community maintained list. Contributions are welcome! ❤️
|
||||
📣 [This is a community maintained list](https://github.com/BerriAI/litellm/blob/main/model_prices_and_context_window.json). Contributions are welcome! ❤️
|
||||
|
||||
## Example Usage
|
||||
|
||||
|
|
|
@ -2,26 +2,37 @@
|
|||
For companies that need SSO, user management and professional support for LiteLLM Proxy
|
||||
|
||||
:::info
|
||||
|
||||
Interested in Enterprise? Schedule a meeting with us here 👉
|
||||
[Talk to founders](https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat)
|
||||
|
||||
:::
|
||||
|
||||
This covers:
|
||||
- ✅ **Features under the [LiteLLM Commercial License (Content Mod, Custom Tags, etc.)](https://docs.litellm.ai/docs/proxy/enterprise)**
|
||||
- ✅ [**Secure UI access with Single Sign-On**](../docs/proxy/ui.md#setup-ssoauth-for-ui)
|
||||
- ✅ [**Audit Logs with retention policy**](../docs/proxy/enterprise.md#audit-logs)
|
||||
- ✅ [**JWT-Auth**](../docs/proxy/token_auth.md)
|
||||
- ✅ [**Control available public, private routes**](../docs/proxy/enterprise.md#control-available-public-private-routes)
|
||||
- ✅ [**Guardrails, Content Moderation, PII Masking, Secret/API Key Masking**](../docs/proxy/enterprise.md#prompt-injection-detection---lakeraai)
|
||||
- ✅ [**Prompt Injection Detection**](../docs/proxy/enterprise.md#prompt-injection-detection---lakeraai)
|
||||
- ✅ [**Invite Team Members to access `/spend` Routes**](../docs/proxy/cost_tracking#allowing-non-proxy-admins-to-access-spend-endpoints)
|
||||
- **Enterprise Features**
|
||||
- **Security**
|
||||
- ✅ [SSO for Admin UI](./proxy/ui#✨-enterprise-features)
|
||||
- ✅ [Audit Logs with retention policy](./proxy/enterprise#audit-logs)
|
||||
- ✅ [JWT-Auth](../docs/proxy/token_auth.md)
|
||||
- ✅ [Control available public, private routes](./proxy/enterprise#control-available-public-private-routes)
|
||||
- ✅ [[BETA] AWS Key Manager v2 - Key Decryption](./proxy/enterprise#beta-aws-key-manager---key-decryption)
|
||||
- ✅ [Use LiteLLM keys/authentication on Pass Through Endpoints](./proxy/pass_through#✨-enterprise---use-litellm-keysauthentication-on-pass-through-endpoints)
|
||||
- ✅ [Enforce Required Params for LLM Requests (ex. Reject requests missing ["metadata"]["generation_name"])](./proxy/enterprise#enforce-required-params-for-llm-requests)
|
||||
- **Spend Tracking**
|
||||
- ✅ [Tracking Spend for Custom Tags](./proxy/enterprise#tracking-spend-for-custom-tags)
|
||||
- ✅ [API Endpoints to get Spend Reports per Team, API Key, Customer](./proxy/cost_tracking.md#✨-enterprise-api-endpoints-to-get-spend)
|
||||
- **Guardrails, PII Masking, Content Moderation**
|
||||
- ✅ [Content Moderation with LLM Guard, LlamaGuard, Secret Detection, Google Text Moderations](./proxy/enterprise#content-moderation)
|
||||
- ✅ [Prompt Injection Detection (with LakeraAI API)](./proxy/enterprise#prompt-injection-detection---lakeraai)
|
||||
- ✅ Reject calls from Blocked User list
|
||||
- ✅ Reject calls (incoming / outgoing) with Banned Keywords (e.g. competitors)
|
||||
- **Custom Branding**
|
||||
- ✅ [Custom Branding + Routes on Swagger Docs](./proxy/enterprise#swagger-docs---custom-routes--branding)
|
||||
- ✅ [Public Model Hub](../docs/proxy/enterprise.md#public-model-hub)
|
||||
- ✅ [Custom Email Branding](../docs/proxy/email.md#customizing-email-branding)
|
||||
- ✅ **Feature Prioritization**
|
||||
- ✅ **Custom Integrations**
|
||||
- ✅ **Professional Support - Dedicated discord + slack**
|
||||
- ✅ [**Custom Swagger**](../docs/proxy/enterprise.md#swagger-docs---custom-routes--branding)
|
||||
- ✅ [**Public Model Hub**](../docs/proxy/enterprise.md#public-model-hub)
|
||||
- ✅ [**Custom Email Branding**](../docs/proxy/email.md#customizing-email-branding)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -168,11 +168,15 @@ print(response)
|
|||
|
||||
## Supported Models
|
||||
|
||||
`Model Name` 👉 Human-friendly name.
|
||||
`Function Call` 👉 How to call the model in LiteLLM.
|
||||
|
||||
| Model Name | Function Call |
|
||||
|------------------|--------------------------------------------|
|
||||
| claude-3-5-sonnet | `completion('claude-3-5-sonnet-20240620', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-3-haiku | `completion('claude-3-haiku-20240307', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-3-opus | `completion('claude-3-opus-20240229', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-3-5-sonnet | `completion('claude-3-5-sonnet-20240620', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-3-5-sonnet-20240620 | `completion('claude-3-5-sonnet-20240620', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-3-sonnet | `completion('claude-3-sonnet-20240229', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-2.1 | `completion('claude-2.1', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
| claude-2 | `completion('claude-2', messages)` | `os.environ['ANTHROPIC_API_KEY']` |
|
||||
|
|
|
@ -27,7 +27,7 @@ import os
|
|||
os.environ["DATABRICKS_API_KEY"] = "databricks key"
|
||||
os.environ["DATABRICKS_API_BASE"] = "databricks base url" # e.g.: https://adb-3064715882934586.6.azuredatabricks.net/serving-endpoints
|
||||
|
||||
# predibase llama-3 call
|
||||
# Databricks dbrx-instruct call
|
||||
response = completion(
|
||||
model="databricks/databricks-dbrx-instruct",
|
||||
messages = [{ "content": "Hello, how are you?","role": "user"}]
|
||||
|
@ -143,13 +143,13 @@ response = completion(
|
|||
model_list:
|
||||
- model_name: llama-3
|
||||
litellm_params:
|
||||
model: predibase/llama-3-8b-instruct
|
||||
api_key: os.environ/PREDIBASE_API_KEY
|
||||
model: databricks/databricks-meta-llama-3-70b-instruct
|
||||
api_key: os.environ/DATABRICKS_API_KEY
|
||||
max_tokens: 20
|
||||
temperature: 0.5
|
||||
```
|
||||
|
||||
## Passings Database specific params - 'instruction'
|
||||
## Passings Databricks specific params - 'instruction'
|
||||
|
||||
For embedding models, databricks lets you pass in an additional param 'instruction'. [Full Spec](https://github.com/BerriAI/litellm/blob/43353c28b341df0d9992b45c6ce464222ebd7984/litellm/llms/databricks.py#L164)
|
||||
|
||||
|
@ -162,7 +162,7 @@ import os
|
|||
os.environ["DATABRICKS_API_KEY"] = "databricks key"
|
||||
os.environ["DATABRICKS_API_BASE"] = "databricks url"
|
||||
|
||||
# predibase llama3 call
|
||||
# Databricks bge-large-en call
|
||||
response = litellm.embedding(
|
||||
model="databricks/databricks-bge-large-en",
|
||||
input=["good morning from litellm"],
|
||||
|
@ -184,7 +184,6 @@ response = litellm.embedding(
|
|||
|
||||
|
||||
## Supported Databricks Chat Completion Models
|
||||
Here's an example of using a Databricks models with LiteLLM
|
||||
|
||||
| Model Name | Command |
|
||||
|----------------------------|------------------------------------------------------------------|
|
||||
|
@ -196,8 +195,8 @@ Here's an example of using a Databricks models with LiteLLM
|
|||
| databricks-mpt-7b-instruct | `completion(model='databricks/databricks-mpt-7b-instruct', messages=messages)` |
|
||||
|
||||
## Supported Databricks Embedding Models
|
||||
Here's an example of using a databricks models with LiteLLM
|
||||
|
||||
| Model Name | Command |
|
||||
|----------------------------|------------------------------------------------------------------|
|
||||
| databricks-bge-large-en | `completion(model='databricks/databricks-bge-large-en', messages=messages)` |
|
||||
| databricks-bge-large-en | `embedding(model='databricks/databricks-bge-large-en', messages=messages)` |
|
||||
| databricks-gte-large-en | `embedding(model='databricks/databricks-gte-large-en', messages=messages)` |
|
||||
|
|
|
@ -115,3 +115,18 @@ Here's how to call an OpenAI-Compatible Endpoint with the LiteLLM Proxy Server
|
|||
</TabItem>
|
||||
|
||||
</Tabs>
|
||||
|
||||
|
||||
### Advanced - Disable System Messages
|
||||
|
||||
Some VLLM models (e.g. gemma) don't support system messages. To map those requests to 'user' messages, use the `supports_system_message` flag.
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: my-custom-model
|
||||
litellm_params:
|
||||
model: openai/google/gemma
|
||||
api_base: http://my-custom-base
|
||||
api_key: ""
|
||||
supports_system_message: False # 👈 KEY CHANGE
|
||||
```
|
|
@ -123,6 +123,45 @@ print(completion(**data))
|
|||
|
||||
### **JSON Schema**
|
||||
|
||||
From v`1.40.1+` LiteLLM supports sending `response_schema` as a param for Gemini-Pro-1.5 on Vertex AI.
|
||||
|
||||
```python
|
||||
from litellm import completion
|
||||
import json
|
||||
|
||||
## SETUP ENVIRONMENT
|
||||
# !gcloud auth application-default login - run this to add vertex credentials to your env
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "List 5 popular cookie recipes."
|
||||
}
|
||||
]
|
||||
|
||||
response_schema = {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"recipe_name": {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": ["recipe_name"],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
completion(
|
||||
model="vertex_ai_beta/gemini-1.5-pro",
|
||||
messages=messages,
|
||||
response_format={"type": "json_object", "response_schema": response_schema} # 👈 KEY CHANGE
|
||||
)
|
||||
|
||||
print(json.loads(completion.choices[0].message.content))
|
||||
```
|
||||
|
||||
```python
|
||||
from litellm import completion
|
||||
|
||||
|
@ -645,6 +684,86 @@ assert isinstance(
|
|||
```
|
||||
|
||||
|
||||
## Usage - PDF / Videos / etc. Files
|
||||
|
||||
Pass any file supported by Vertex AI, through LiteLLM.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="sdk" label="SDK">
|
||||
|
||||
```python
|
||||
from litellm import completion
|
||||
|
||||
response = completion(
|
||||
model="vertex_ai/gemini-1.5-flash",
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "You are a very professional document summarization specialist. Please summarize the given document."},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": "gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf",
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
max_tokens=300,
|
||||
)
|
||||
|
||||
print(response.choices[0])
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="proxy" lable="PROXY">
|
||||
|
||||
1. Add model to config
|
||||
|
||||
```yaml
|
||||
- model_name: gemini-1.5-flash
|
||||
litellm_params:
|
||||
model: vertex_ai/gemini-1.5-flash
|
||||
vertex_credentials: "/path/to/service_account.json"
|
||||
```
|
||||
|
||||
2. Start Proxy
|
||||
|
||||
```
|
||||
litellm --config /path/to/config.yaml
|
||||
```
|
||||
|
||||
3. Test it!
|
||||
|
||||
```bash
|
||||
curl http://0.0.0.0:4000/v1/chat/completions \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer <YOUR-LITELLM-KEY>" \
|
||||
-d '{
|
||||
"model": "gemini-1.5-flash",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "You are a very professional document summarization specialist. Please summarize the given document"
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": "gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"max_tokens": 300
|
||||
}'
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Chat Models
|
||||
| Model Name | Function Call |
|
||||
|------------------|--------------------------------------|
|
||||
|
|
98
docs/my-website/docs/providers/volcano.md
Normal file
98
docs/my-website/docs/providers/volcano.md
Normal file
|
@ -0,0 +1,98 @@
|
|||
# Volcano Engine (Volcengine)
|
||||
https://www.volcengine.com/docs/82379/1263482
|
||||
|
||||
:::tip
|
||||
|
||||
**We support ALL Volcengine NIM models, just set `model=volcengine/<any-model-on-volcengine>` as a prefix when sending litellm requests**
|
||||
|
||||
:::
|
||||
|
||||
## API Key
|
||||
```python
|
||||
# env variable
|
||||
os.environ['VOLCENGINE_API_KEY']
|
||||
```
|
||||
|
||||
## Sample Usage
|
||||
```python
|
||||
from litellm import completion
|
||||
import os
|
||||
|
||||
os.environ['VOLCENGINE_API_KEY'] = ""
|
||||
response = completion(
|
||||
model="volcengine/<OUR_ENDPOINT_ID>",
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What's the weather like in Boston today in Fahrenheit?",
|
||||
}
|
||||
],
|
||||
temperature=0.2, # optional
|
||||
top_p=0.9, # optional
|
||||
frequency_penalty=0.1, # optional
|
||||
presence_penalty=0.1, # optional
|
||||
max_tokens=10, # optional
|
||||
stop=["\n\n"], # optional
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
## Sample Usage - Streaming
|
||||
```python
|
||||
from litellm import completion
|
||||
import os
|
||||
|
||||
os.environ['VOLCENGINE_API_KEY'] = ""
|
||||
response = completion(
|
||||
model="volcengine/<OUR_ENDPOINT_ID>",
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What's the weather like in Boston today in Fahrenheit?",
|
||||
}
|
||||
],
|
||||
stream=True,
|
||||
temperature=0.2, # optional
|
||||
top_p=0.9, # optional
|
||||
frequency_penalty=0.1, # optional
|
||||
presence_penalty=0.1, # optional
|
||||
max_tokens=10, # optional
|
||||
stop=["\n\n"], # optional
|
||||
)
|
||||
|
||||
for chunk in response:
|
||||
print(chunk)
|
||||
```
|
||||
|
||||
|
||||
## Supported Models - 💥 ALL Volcengine NIM Models Supported!
|
||||
We support ALL `volcengine` models, just set `volcengine/<OUR_ENDPOINT_ID>` as a prefix when sending completion requests
|
||||
|
||||
## Sample Usage - LiteLLM Proxy
|
||||
|
||||
### Config.yaml setting
|
||||
|
||||
```yaml
|
||||
model_list:
|
||||
- model_name: volcengine-model
|
||||
litellm_params:
|
||||
model: volcengine/<OUR_ENDPOINT_ID>
|
||||
api_key: os.environ/VOLCENGINE_API_KEY
|
||||
```
|
||||
|
||||
### Send Request
|
||||
|
||||
```shell
|
||||
curl --location 'http://localhost:4000/chat/completions' \
|
||||
--header 'Authorization: Bearer sk-1234' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data '{
|
||||
"model": "volcengine-model",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "here is my api key. openai_api_key=sk-1234"
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
|
@ -280,14 +280,14 @@ curl --location 'http://0.0.0.0:4000/v1/model/info' \
|
|||
## Load Balancing
|
||||
|
||||
:::info
|
||||
For more on this, go to [this page](./load_balancing.md)
|
||||
For more on this, go to [this page](https://docs.litellm.ai/docs/proxy/load_balancing)
|
||||
:::
|
||||
|
||||
Use this to call multiple instances of the same model and configure things like [routing strategy](../routing.md#advanced).
|
||||
Use this to call multiple instances of the same model and configure things like [routing strategy](https://docs.litellm.ai/docs/routing#advanced).
|
||||
|
||||
For optimal performance:
|
||||
- Set `tpm/rpm` per model deployment. Weighted picks are then based on the established tpm/rpm.
|
||||
- Select your optimal routing strategy in `router_settings:routing_strategy`.
|
||||
- Select your optimal routing strategy in `router_settings:routing_strategy`.
|
||||
|
||||
LiteLLM supports
|
||||
```python
|
||||
|
@ -427,7 +427,7 @@ model_list:
|
|||
|
||||
```shell
|
||||
$ litellm --config /path/to/config.yaml
|
||||
```
|
||||
```
|
||||
|
||||
## Setting Embedding Models
|
||||
|
||||
|
|
|
@ -114,6 +114,16 @@ print(response)
|
|||
**Step3 - Verify Spend Tracked**
|
||||
That's IT. Now Verify your spend was tracked
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="curl" label="Response Headers">
|
||||
|
||||
Expect to see `x-litellm-response-cost` in the response headers with calculated cost
|
||||
|
||||
<Image img={require('../../img/response_cost_img.png')} />
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="db" label="DB + UI">
|
||||
|
||||
The following spend gets tracked in Table `LiteLLM_SpendLogs`
|
||||
|
||||
```json
|
||||
|
@ -137,12 +147,16 @@ Navigate to the Usage Tab on the LiteLLM UI (found on https://your-proxy-endpoin
|
|||
|
||||
<Image img={require('../../img/admin_ui_spend.png')} />
|
||||
|
||||
## API Endpoints to get Spend
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## ✨ (Enterprise) API Endpoints to get Spend
|
||||
#### Getting Spend Reports - To Charge Other Teams, Customers
|
||||
|
||||
Use the `/global/spend/report` endpoint to get daily spend report per
|
||||
- team
|
||||
- customer [this is `user` passed to `/chat/completions` request](#how-to-track-spend-with-litellm)
|
||||
- Team
|
||||
- Customer [this is `user` passed to `/chat/completions` request](#how-to-track-spend-with-litellm)
|
||||
- [LiteLLM API key](virtual_keys.md)
|
||||
|
||||
<Tabs>
|
||||
|
||||
|
@ -325,6 +339,61 @@ curl -X GET 'http://localhost:4000/global/spend/report?start_date=2024-04-01&end
|
|||
```
|
||||
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="per key" label="Spend Per API Key">
|
||||
|
||||
|
||||
👉 Key Change: Specify `group_by=api_key`
|
||||
|
||||
|
||||
```shell
|
||||
curl -X GET 'http://localhost:4000/global/spend/report?start_date=2024-04-01&end_date=2024-06-30&group_by=api_key' \
|
||||
-H 'Authorization: Bearer sk-1234'
|
||||
```
|
||||
|
||||
##### Example Response
|
||||
|
||||
|
||||
```shell
|
||||
[
|
||||
{
|
||||
"api_key": "ad64768847d05d978d62f623d872bff0f9616cc14b9c1e651c84d14fe3b9f539",
|
||||
"total_cost": 0.0002157,
|
||||
"total_input_tokens": 45.0,
|
||||
"total_output_tokens": 1375.0,
|
||||
"model_details": [
|
||||
{
|
||||
"model": "gpt-3.5-turbo",
|
||||
"total_cost": 0.0001095,
|
||||
"total_input_tokens": 9,
|
||||
"total_output_tokens": 70
|
||||
},
|
||||
{
|
||||
"model": "llama3-8b-8192",
|
||||
"total_cost": 0.0001062,
|
||||
"total_input_tokens": 36,
|
||||
"total_output_tokens": 1305
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"api_key": "88dc28d0f030c55ed4ab77ed8faf098196cb1c05df778539800c9f1243fe6b4b",
|
||||
"total_cost": 0.00012924,
|
||||
"total_input_tokens": 36.0,
|
||||
"total_output_tokens": 1593.0,
|
||||
"model_details": [
|
||||
{
|
||||
"model": "llama3-8b-8192",
|
||||
"total_cost": 0.00012924,
|
||||
"total_input_tokens": 36,
|
||||
"total_output_tokens": 1593
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
</Tabs>
|
||||
|
|
|
@ -6,21 +6,32 @@ import TabItem from '@theme/TabItem';
|
|||
|
||||
:::tip
|
||||
|
||||
Get in touch with us [here](https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat)
|
||||
To get a license, get in touch with us [here](https://calendly.com/d/4mp-gd3-k5k/litellm-1-1-onboarding-chat)
|
||||
|
||||
:::
|
||||
|
||||
Features:
|
||||
- ✅ [SSO for Admin UI](./ui.md#✨-enterprise-features)
|
||||
- ✅ [Audit Logs](#audit-logs)
|
||||
- ✅ [Tracking Spend for Custom Tags](#tracking-spend-for-custom-tags)
|
||||
- ✅ [Control available public, private routes](#control-available-public-private-routes)
|
||||
- ✅ [Content Moderation with LLM Guard, LlamaGuard, Secret Detection, Google Text Moderations](#content-moderation)
|
||||
- ✅ [Prompt Injection Detection (with LakeraAI API)](#prompt-injection-detection---lakeraai)
|
||||
- ✅ [Custom Branding + Routes on Swagger Docs](#swagger-docs---custom-routes--branding)
|
||||
- ✅ [Enforce Required Params for LLM Requests (ex. Reject requests missing ["metadata"]["generation_name"])](#enforce-required-params-for-llm-requests)
|
||||
- ✅ Reject calls from Blocked User list
|
||||
- ✅ Reject calls (incoming / outgoing) with Banned Keywords (e.g. competitors)
|
||||
|
||||
- **Security**
|
||||
- ✅ [SSO for Admin UI](./ui.md#✨-enterprise-features)
|
||||
- ✅ [Audit Logs with retention policy](#audit-logs)
|
||||
- ✅ [JWT-Auth](../docs/proxy/token_auth.md)
|
||||
- ✅ [Control available public, private routes](#control-available-public-private-routes)
|
||||
- ✅ [[BETA] AWS Key Manager v2 - Key Decryption](#beta-aws-key-manager---key-decryption)
|
||||
- ✅ [Use LiteLLM keys/authentication on Pass Through Endpoints](pass_through#✨-enterprise---use-litellm-keysauthentication-on-pass-through-endpoints)
|
||||
- ✅ [Enforce Required Params for LLM Requests (ex. Reject requests missing ["metadata"]["generation_name"])](#enforce-required-params-for-llm-requests)
|
||||
- **Spend Tracking**
|
||||
- ✅ [Tracking Spend for Custom Tags](#tracking-spend-for-custom-tags)
|
||||
- ✅ [API Endpoints to get Spend Reports per Team, API Key, Customer](cost_tracking.md#✨-enterprise-api-endpoints-to-get-spend)
|
||||
- **Guardrails, PII Masking, Content Moderation**
|
||||
- ✅ [Content Moderation with LLM Guard, LlamaGuard, Secret Detection, Google Text Moderations](#content-moderation)
|
||||
- ✅ [Prompt Injection Detection (with LakeraAI API)](#prompt-injection-detection---lakeraai)
|
||||
- ✅ Reject calls from Blocked User list
|
||||
- ✅ Reject calls (incoming / outgoing) with Banned Keywords (e.g. competitors)
|
||||
- **Custom Branding**
|
||||
- ✅ [Custom Branding + Routes on Swagger Docs](#swagger-docs---custom-routes--branding)
|
||||
- ✅ [Public Model Hub](../docs/proxy/enterprise.md#public-model-hub)
|
||||
- ✅ [Custom Email Branding](../docs/proxy/email.md#customizing-email-branding)
|
||||
|
||||
## Audit Logs
|
||||
|
||||
|
@ -1019,4 +1030,35 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \
|
|||
|
||||
Share a public page of available models for users
|
||||
|
||||
<Image img={require('../../img/model_hub.png')} style={{ width: '900px', height: 'auto' }}/>
|
||||
<Image img={require('../../img/model_hub.png')} style={{ width: '900px', height: 'auto' }}/>
|
||||
|
||||
|
||||
## [BETA] AWS Key Manager - Key Decryption
|
||||
|
||||
This is a beta feature, and subject to changes.
|
||||
|
||||
|
||||
**Step 1.** Add `USE_AWS_KMS` to env
|
||||
|
||||
```env
|
||||
USE_AWS_KMS="True"
|
||||
```
|
||||
|
||||
**Step 2.** Add `aws_kms/` to encrypted keys in env
|
||||
|
||||
```env
|
||||
DATABASE_URL="aws_kms/AQICAH.."
|
||||
```
|
||||
|
||||
**Step 3.** Start proxy
|
||||
|
||||
```
|
||||
$ litellm
|
||||
```
|
||||
|
||||
How it works?
|
||||
- Key Decryption runs before server starts up. [**Code**](https://github.com/BerriAI/litellm/blob/8571cb45e80cc561dc34bc6aa89611eb96b9fe3e/litellm/proxy/proxy_cli.py#L445)
|
||||
- It adds the decrypted value to the `os.environ` for the python process.
|
||||
|
||||
**Note:** Setting an environment variable within a Python script using os.environ will not make that variable accessible via SSH sessions or any other new processes that are started independently of the Python script. Environment variables set this way only affect the current process and its child processes.
|
||||
|
||||
|
|
220
docs/my-website/docs/proxy/pass_through.md
Normal file
220
docs/my-website/docs/proxy/pass_through.md
Normal file
|
@ -0,0 +1,220 @@
|
|||
import Image from '@theme/IdealImage';
|
||||
|
||||
# ➡️ Create Pass Through Endpoints
|
||||
|
||||
Add pass through routes to LiteLLM Proxy
|
||||
|
||||
**Example:** Add a route `/v1/rerank` that forwards requests to `https://api.cohere.com/v1/rerank` through LiteLLM Proxy
|
||||
|
||||
|
||||
💡 This allows making the following Request to LiteLLM Proxy
|
||||
```shell
|
||||
curl --request POST \
|
||||
--url http://localhost:4000/v1/rerank \
|
||||
--header 'accept: application/json' \
|
||||
--header 'content-type: application/json' \
|
||||
--data '{
|
||||
"model": "rerank-english-v3.0",
|
||||
"query": "What is the capital of the United States?",
|
||||
"top_n": 3,
|
||||
"documents": ["Carson City is the capital city of the American state of Nevada."]
|
||||
}'
|
||||
```
|
||||
|
||||
## Tutorial - Pass through Cohere Re-Rank Endpoint
|
||||
|
||||
**Step 1** Define pass through routes on [litellm config.yaml](configs.md)
|
||||
|
||||
```yaml
|
||||
general_settings:
|
||||
master_key: sk-1234
|
||||
pass_through_endpoints:
|
||||
- path: "/v1/rerank" # route you want to add to LiteLLM Proxy Server
|
||||
target: "https://api.cohere.com/v1/rerank" # URL this route should forward requests to
|
||||
headers: # headers to forward to this URL
|
||||
Authorization: "bearer os.environ/COHERE_API_KEY" # (Optional) Auth Header to forward to your Endpoint
|
||||
content-type: application/json # (Optional) Extra Headers to pass to this endpoint
|
||||
accept: application/json
|
||||
```
|
||||
|
||||
**Step 2** Start Proxy Server in detailed_debug mode
|
||||
|
||||
```shell
|
||||
litellm --config config.yaml --detailed_debug
|
||||
```
|
||||
**Step 3** Make Request to pass through endpoint
|
||||
|
||||
Here `http://localhost:4000` is your litellm proxy endpoint
|
||||
|
||||
```shell
|
||||
curl --request POST \
|
||||
--url http://localhost:4000/v1/rerank \
|
||||
--header 'accept: application/json' \
|
||||
--header 'content-type: application/json' \
|
||||
--data '{
|
||||
"model": "rerank-english-v3.0",
|
||||
"query": "What is the capital of the United States?",
|
||||
"top_n": 3,
|
||||
"documents": ["Carson City is the capital city of the American state of Nevada.",
|
||||
"The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean. Its capital is Saipan.",
|
||||
"Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.",
|
||||
"Capitalization or capitalisation in English grammar is the use of a capital letter at the start of a word. English usage varies from capitalization in other languages.",
|
||||
"Capital punishment (the death penalty) has existed in the United States since beforethe United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states."]
|
||||
}'
|
||||
```
|
||||
|
||||
|
||||
🎉 **Expected Response**
|
||||
|
||||
This request got forwarded from LiteLLM Proxy -> Defined Target URL (with headers)
|
||||
|
||||
```shell
|
||||
{
|
||||
"id": "37103a5b-8cfb-48d3-87c7-da288bedd429",
|
||||
"results": [
|
||||
{
|
||||
"index": 2,
|
||||
"relevance_score": 0.999071
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"relevance_score": 0.7867867
|
||||
},
|
||||
{
|
||||
"index": 0,
|
||||
"relevance_score": 0.32713068
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"api_version": {
|
||||
"version": "1"
|
||||
},
|
||||
"billed_units": {
|
||||
"search_units": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tutorial - Pass Through Langfuse Requests
|
||||
|
||||
|
||||
**Step 1** Define pass through routes on [litellm config.yaml](configs.md)
|
||||
|
||||
```yaml
|
||||
general_settings:
|
||||
master_key: sk-1234
|
||||
pass_through_endpoints:
|
||||
- path: "/api/public/ingestion" # route you want to add to LiteLLM Proxy Server
|
||||
target: "https://us.cloud.langfuse.com/api/public/ingestion" # URL this route should forward
|
||||
headers:
|
||||
LANGFUSE_PUBLIC_KEY: "os.environ/LANGFUSE_DEV_PUBLIC_KEY" # your langfuse account public key
|
||||
LANGFUSE_SECRET_KEY: "os.environ/LANGFUSE_DEV_SK_KEY" # your langfuse account secret key
|
||||
```
|
||||
|
||||
**Step 2** Start Proxy Server in detailed_debug mode
|
||||
|
||||
```shell
|
||||
litellm --config config.yaml --detailed_debug
|
||||
```
|
||||
**Step 3** Make Request to pass through endpoint
|
||||
|
||||
Run this code to make a sample trace
|
||||
```python
|
||||
from langfuse import Langfuse
|
||||
|
||||
langfuse = Langfuse(
|
||||
host="http://localhost:4000", # your litellm proxy endpoint
|
||||
public_key="anything", # no key required since this is a pass through
|
||||
secret_key="anything", # no key required since this is a pass through
|
||||
)
|
||||
|
||||
print("sending langfuse trace request")
|
||||
trace = langfuse.trace(name="test-trace-litellm-proxy-passthrough")
|
||||
print("flushing langfuse request")
|
||||
langfuse.flush()
|
||||
|
||||
print("flushed langfuse request")
|
||||
```
|
||||
|
||||
|
||||
🎉 **Expected Response**
|
||||
|
||||
On success
|
||||
Expect to see the following Trace Generated on your Langfuse Dashboard
|
||||
|
||||
<Image img={require('../../img/proxy_langfuse.png')} />
|
||||
|
||||
You will see the following endpoint called on your litellm proxy server logs
|
||||
|
||||
```shell
|
||||
POST /api/public/ingestion HTTP/1.1" 207 Multi-Status
|
||||
```
|
||||
|
||||
|
||||
## ✨ [Enterprise] - Use LiteLLM keys/authentication on Pass Through Endpoints
|
||||
|
||||
Use this if you want the pass through endpoint to honour LiteLLM keys/authentication
|
||||
|
||||
Usage - set `auth: true` on the config
|
||||
```yaml
|
||||
general_settings:
|
||||
master_key: sk-1234
|
||||
pass_through_endpoints:
|
||||
- path: "/v1/rerank"
|
||||
target: "https://api.cohere.com/v1/rerank"
|
||||
auth: true # 👈 Key change to use LiteLLM Auth / Keys
|
||||
headers:
|
||||
Authorization: "bearer os.environ/COHERE_API_KEY"
|
||||
content-type: application/json
|
||||
accept: application/json
|
||||
```
|
||||
|
||||
Test Request with LiteLLM Key
|
||||
|
||||
```shell
|
||||
curl --request POST \
|
||||
--url http://localhost:4000/v1/rerank \
|
||||
--header 'accept: application/json' \
|
||||
--header 'Authorization: Bearer sk-1234'\
|
||||
--header 'content-type: application/json' \
|
||||
--data '{
|
||||
"model": "rerank-english-v3.0",
|
||||
"query": "What is the capital of the United States?",
|
||||
"top_n": 3,
|
||||
"documents": ["Carson City is the capital city of the American state of Nevada.",
|
||||
"The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean. Its capital is Saipan.",
|
||||
"Washington, D.C. (also known as simply Washington or D.C., and officially as the District of Columbia) is the capital of the United States. It is a federal district.",
|
||||
"Capitalization or capitalisation in English grammar is the use of a capital letter at the start of a word. English usage varies from capitalization in other languages.",
|
||||
"Capital punishment (the death penalty) has existed in the United States since beforethe United States was a country. As of 2017, capital punishment is legal in 30 of the 50 states."]
|
||||
}'
|
||||
```
|
||||
|
||||
## `pass_through_endpoints` Spec on config.yaml
|
||||
|
||||
All possible values for `pass_through_endpoints` and what they mean
|
||||
|
||||
**Example config**
|
||||
```yaml
|
||||
general_settings:
|
||||
pass_through_endpoints:
|
||||
- path: "/v1/rerank" # route you want to add to LiteLLM Proxy Server
|
||||
target: "https://api.cohere.com/v1/rerank" # URL this route should forward requests to
|
||||
headers: # headers to forward to this URL
|
||||
Authorization: "bearer os.environ/COHERE_API_KEY" # (Optional) Auth Header to forward to your Endpoint
|
||||
content-type: application/json # (Optional) Extra Headers to pass to this endpoint
|
||||
accept: application/json
|
||||
```
|
||||
|
||||
**Spec**
|
||||
|
||||
* `pass_through_endpoints` *list*: A collection of endpoint configurations for request forwarding.
|
||||
* `path` *string*: The route to be added to the LiteLLM Proxy Server.
|
||||
* `target` *string*: The URL to which requests for this path should be forwarded.
|
||||
* `headers` *object*: Key-value pairs of headers to be forwarded with the request. You can set any key value pair here and it will be forwarded to your target endpoint
|
||||
* `Authorization` *string*: The authentication header for the target API.
|
||||
* `content-type` *string*: The format specification for the request body.
|
||||
* `accept` *string*: The expected response format from the server.
|
||||
* `LANGFUSE_PUBLIC_KEY` *string*: Your Langfuse account public key - only set this when forwarding to Langfuse.
|
||||
* `LANGFUSE_SECRET_KEY` *string*: Your Langfuse account secret key - only set this when forwarding to Langfuse.
|
||||
* `<your-custom-header>` *string*: Pass any custom header key/value pair
|
|
@ -4,7 +4,7 @@ import TabItem from '@theme/TabItem';
|
|||
|
||||
# 🤗 UI - Self-Serve
|
||||
|
||||
Allow users to creat their own keys on [Proxy UI](./ui.md).
|
||||
Allow users to create their own keys on [Proxy UI](./ui.md).
|
||||
|
||||
1. Add user with permissions to a team on proxy
|
||||
|
||||
|
|
|
@ -8,7 +8,13 @@ LiteLLM supports reading secrets from Azure Key Vault and Infisical
|
|||
- [Infisical Secret Manager](#infisical-secret-manager)
|
||||
- [.env Files](#env-files)
|
||||
|
||||
## AWS Key Management Service
|
||||
## AWS Key Management V1
|
||||
|
||||
:::tip
|
||||
|
||||
[BETA] AWS Key Management v2 is on the enterprise tier. Go [here for docs](./proxy/enterprise.md#beta-aws-key-manager---key-decryption)
|
||||
|
||||
:::
|
||||
|
||||
Use AWS KMS to storing a hashed copy of your Proxy Master Key in the environment.
|
||||
|
||||
|
|
|
@ -14,14 +14,6 @@ response = speech(
|
|||
model="openai/tts-1",
|
||||
voice="alloy",
|
||||
input="the quick brown fox jumped over the lazy dogs",
|
||||
api_base=None,
|
||||
api_key=None,
|
||||
organization=None,
|
||||
project=None,
|
||||
max_retries=1,
|
||||
timeout=600,
|
||||
client=None,
|
||||
optional_params={},
|
||||
)
|
||||
response.stream_to_file(speech_file_path)
|
||||
```
|
||||
|
@ -84,4 +76,37 @@ curl http://0.0.0.0:4000/v1/audio/speech \
|
|||
litellm --config /path/to/config.yaml
|
||||
|
||||
# RUNNING on http://0.0.0.0:4000
|
||||
```
|
||||
|
||||
## Azure Usage
|
||||
|
||||
**PROXY**
|
||||
|
||||
```yaml
|
||||
- model_name: azure/tts-1
|
||||
litellm_params:
|
||||
model: azure/tts-1
|
||||
api_base: "os.environ/AZURE_API_BASE_TTS"
|
||||
api_key: "os.environ/AZURE_API_KEY_TTS"
|
||||
api_version: "os.environ/AZURE_API_VERSION"
|
||||
```
|
||||
|
||||
**SDK**
|
||||
|
||||
```python
|
||||
from litellm import completion
|
||||
|
||||
## set ENV variables
|
||||
os.environ["AZURE_API_KEY"] = ""
|
||||
os.environ["AZURE_API_BASE"] = ""
|
||||
os.environ["AZURE_API_VERSION"] = ""
|
||||
|
||||
# azure call
|
||||
speech_file_path = Path(__file__).parent / "speech.mp3"
|
||||
response = speech(
|
||||
model="azure/<your-deployment-name",
|
||||
voice="alloy",
|
||||
input="the quick brown fox jumped over the lazy dogs",
|
||||
)
|
||||
response.stream_to_file(speech_file_path)
|
||||
```
|
BIN
docs/my-website/img/proxy_langfuse.png
Normal file
BIN
docs/my-website/img/proxy_langfuse.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 212 KiB |
BIN
docs/my-website/img/response_cost_img.png
Normal file
BIN
docs/my-website/img/response_cost_img.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 206 KiB |
|
@ -48,6 +48,7 @@ const sidebars = {
|
|||
"proxy/billing",
|
||||
"proxy/user_keys",
|
||||
"proxy/virtual_keys",
|
||||
"proxy/token_auth",
|
||||
"proxy/alerting",
|
||||
{
|
||||
type: "category",
|
||||
|
@ -56,11 +57,11 @@ const sidebars = {
|
|||
},
|
||||
"proxy/ui",
|
||||
"proxy/prometheus",
|
||||
"proxy/pass_through",
|
||||
"proxy/email",
|
||||
"proxy/multiple_admins",
|
||||
"proxy/team_based_routing",
|
||||
"proxy/customer_routing",
|
||||
"proxy/token_auth",
|
||||
{
|
||||
type: "category",
|
||||
label: "Extra Load Balancing",
|
||||
|
@ -147,6 +148,7 @@ const sidebars = {
|
|||
"providers/watsonx",
|
||||
"providers/predibase",
|
||||
"providers/nvidia_nim",
|
||||
"providers/volcano",
|
||||
"providers/triton-inference-server",
|
||||
"providers/ollama",
|
||||
"providers/perplexity",
|
||||
|
|
|
@ -114,7 +114,11 @@ class _ENTERPRISE_lakeraAI_Moderation(CustomLogger):
|
|||
|
||||
if flagged == True:
|
||||
raise HTTPException(
|
||||
status_code=400, detail={"error": "Violated content safety policy"}
|
||||
status_code=400,
|
||||
detail={
|
||||
"error": "Violated content safety policy",
|
||||
"lakera_ai_response": _json_response,
|
||||
},
|
||||
)
|
||||
|
||||
pass
|
||||
|
|
|
@ -33,27 +33,429 @@ from litellm._logging import verbose_proxy_logger
|
|||
litellm.set_verbose = True
|
||||
|
||||
|
||||
_custom_plugins_path = "file://" + os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "secrets_plugins"
|
||||
)
|
||||
print("custom plugins path", _custom_plugins_path)
|
||||
_default_detect_secrets_config = {
|
||||
"plugins_used": [
|
||||
{"name": "SoftlayerDetector"},
|
||||
{"name": "StripeDetector"},
|
||||
{"name": "NpmDetector"},
|
||||
{"name": "IbmCosHmacDetector"},
|
||||
{"name": "DiscordBotTokenDetector"},
|
||||
{"name": "BasicAuthDetector"},
|
||||
{"name": "AzureStorageKeyDetector"},
|
||||
{"name": "ArtifactoryDetector"},
|
||||
{"name": "AWSKeyDetector"},
|
||||
{"name": "CloudantDetector"},
|
||||
{"name": "IbmCloudIamDetector"},
|
||||
{"name": "JwtTokenDetector"},
|
||||
{"name": "MailchimpDetector"},
|
||||
{"name": "SquareOAuthDetector"},
|
||||
{"name": "PrivateKeyDetector"},
|
||||
{"name": "TwilioKeyDetector"},
|
||||
{
|
||||
"name": "AdafruitKeyDetector",
|
||||
"path": _custom_plugins_path + "/adafruit.py",
|
||||
},
|
||||
{
|
||||
"name": "AdobeSecretDetector",
|
||||
"path": _custom_plugins_path + "/adobe.py",
|
||||
},
|
||||
{
|
||||
"name": "AgeSecretKeyDetector",
|
||||
"path": _custom_plugins_path + "/age_secret_key.py",
|
||||
},
|
||||
{
|
||||
"name": "AirtableApiKeyDetector",
|
||||
"path": _custom_plugins_path + "/airtable_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "AlgoliaApiKeyDetector",
|
||||
"path": _custom_plugins_path + "/algolia_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "AlibabaSecretDetector",
|
||||
"path": _custom_plugins_path + "/alibaba.py",
|
||||
},
|
||||
{
|
||||
"name": "AsanaSecretDetector",
|
||||
"path": _custom_plugins_path + "/asana.py",
|
||||
},
|
||||
{
|
||||
"name": "AtlassianApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/atlassian_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "AuthressAccessKeyDetector",
|
||||
"path": _custom_plugins_path + "/authress_access_key.py",
|
||||
},
|
||||
{
|
||||
"name": "BittrexDetector",
|
||||
"path": _custom_plugins_path + "/beamer_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "BitbucketDetector",
|
||||
"path": _custom_plugins_path + "/bitbucket.py",
|
||||
},
|
||||
{
|
||||
"name": "BeamerApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/bittrex.py",
|
||||
},
|
||||
{
|
||||
"name": "ClojarsApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/clojars_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "CodecovAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/codecov_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "CoinbaseAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/coinbase_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "ConfluentDetector",
|
||||
"path": _custom_plugins_path + "/confluent.py",
|
||||
},
|
||||
{
|
||||
"name": "ContentfulApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/contentful_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DatabricksApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/databricks_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DatadogAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/datadog_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DefinedNetworkingApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/defined_networking_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DigitaloceanDetector",
|
||||
"path": _custom_plugins_path + "/digitalocean.py",
|
||||
},
|
||||
{
|
||||
"name": "DopplerApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/doppler_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DroneciAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/droneci_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DuffelApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/duffel_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DynatraceApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/dynatrace_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "DiscordDetector",
|
||||
"path": _custom_plugins_path + "/discord.py",
|
||||
},
|
||||
{
|
||||
"name": "DropboxDetector",
|
||||
"path": _custom_plugins_path + "/dropbox.py",
|
||||
},
|
||||
{
|
||||
"name": "EasyPostDetector",
|
||||
"path": _custom_plugins_path + "/easypost.py",
|
||||
},
|
||||
{
|
||||
"name": "EtsyAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/etsy_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "FacebookAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/facebook_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "FastlyApiKeyDetector",
|
||||
"path": _custom_plugins_path + "/fastly_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "FinicityDetector",
|
||||
"path": _custom_plugins_path + "/finicity.py",
|
||||
},
|
||||
{
|
||||
"name": "FinnhubAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/finnhub_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "FlickrAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/flickr_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "FlutterwaveDetector",
|
||||
"path": _custom_plugins_path + "/flutterwave.py",
|
||||
},
|
||||
{
|
||||
"name": "FrameIoApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/frameio_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "FreshbooksAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/freshbooks_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "GCPApiKeyDetector",
|
||||
"path": _custom_plugins_path + "/gcp_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "GitHubTokenCustomDetector",
|
||||
"path": _custom_plugins_path + "/github_token.py",
|
||||
},
|
||||
{
|
||||
"name": "GitLabDetector",
|
||||
"path": _custom_plugins_path + "/gitlab.py",
|
||||
},
|
||||
{
|
||||
"name": "GitterAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/gitter_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "GoCardlessApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/gocardless_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "GrafanaDetector",
|
||||
"path": _custom_plugins_path + "/grafana.py",
|
||||
},
|
||||
{
|
||||
"name": "HashiCorpTFApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/hashicorp_tf_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "HerokuApiKeyDetector",
|
||||
"path": _custom_plugins_path + "/heroku_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "HubSpotApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/hubspot_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "HuggingFaceDetector",
|
||||
"path": _custom_plugins_path + "/huggingface.py",
|
||||
},
|
||||
{
|
||||
"name": "IntercomApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/intercom_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "JFrogDetector",
|
||||
"path": _custom_plugins_path + "/jfrog.py",
|
||||
},
|
||||
{
|
||||
"name": "JWTBase64Detector",
|
||||
"path": _custom_plugins_path + "/jwt.py",
|
||||
},
|
||||
{
|
||||
"name": "KrakenAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/kraken_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "KucoinDetector",
|
||||
"path": _custom_plugins_path + "/kucoin.py",
|
||||
},
|
||||
{
|
||||
"name": "LaunchdarklyAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/launchdarkly_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "LinearDetector",
|
||||
"path": _custom_plugins_path + "/linear.py",
|
||||
},
|
||||
{
|
||||
"name": "LinkedInDetector",
|
||||
"path": _custom_plugins_path + "/linkedin.py",
|
||||
},
|
||||
{
|
||||
"name": "LobDetector",
|
||||
"path": _custom_plugins_path + "/lob.py",
|
||||
},
|
||||
{
|
||||
"name": "MailgunDetector",
|
||||
"path": _custom_plugins_path + "/mailgun.py",
|
||||
},
|
||||
{
|
||||
"name": "MapBoxApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/mapbox_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "MattermostAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/mattermost_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "MessageBirdDetector",
|
||||
"path": _custom_plugins_path + "/messagebird.py",
|
||||
},
|
||||
{
|
||||
"name": "MicrosoftTeamsWebhookDetector",
|
||||
"path": _custom_plugins_path + "/microsoft_teams_webhook.py",
|
||||
},
|
||||
{
|
||||
"name": "NetlifyAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/netlify_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "NewRelicDetector",
|
||||
"path": _custom_plugins_path + "/new_relic.py",
|
||||
},
|
||||
{
|
||||
"name": "NYTimesAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/nytimes_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "OktaAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/okta_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "OpenAIApiKeyDetector",
|
||||
"path": _custom_plugins_path + "/openai_api_key.py",
|
||||
},
|
||||
{
|
||||
"name": "PlanetScaleDetector",
|
||||
"path": _custom_plugins_path + "/planetscale.py",
|
||||
},
|
||||
{
|
||||
"name": "PostmanApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/postman_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "PrefectApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/prefect_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "PulumiApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/pulumi_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "PyPiUploadTokenDetector",
|
||||
"path": _custom_plugins_path + "/pypi_upload_token.py",
|
||||
},
|
||||
{
|
||||
"name": "RapidApiAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/rapidapi_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "ReadmeApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/readme_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "RubygemsApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/rubygems_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "ScalingoApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/scalingo_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "SendbirdDetector",
|
||||
"path": _custom_plugins_path + "/sendbird.py",
|
||||
},
|
||||
{
|
||||
"name": "SendGridApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/sendgrid_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "SendinBlueApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/sendinblue_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "SentryAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/sentry_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "ShippoApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/shippo_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "ShopifyDetector",
|
||||
"path": _custom_plugins_path + "/shopify.py",
|
||||
},
|
||||
{
|
||||
"name": "SlackDetector",
|
||||
"path": _custom_plugins_path + "/slack.py",
|
||||
},
|
||||
{
|
||||
"name": "SnykApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/snyk_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "SquarespaceAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/squarespace_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "SumoLogicDetector",
|
||||
"path": _custom_plugins_path + "/sumologic.py",
|
||||
},
|
||||
{
|
||||
"name": "TelegramBotApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/telegram_bot_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "TravisCiAccessTokenDetector",
|
||||
"path": _custom_plugins_path + "/travisci_access_token.py",
|
||||
},
|
||||
{
|
||||
"name": "TwitchApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/twitch_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "TwitterDetector",
|
||||
"path": _custom_plugins_path + "/twitter.py",
|
||||
},
|
||||
{
|
||||
"name": "TypeformApiTokenDetector",
|
||||
"path": _custom_plugins_path + "/typeform_api_token.py",
|
||||
},
|
||||
{
|
||||
"name": "VaultDetector",
|
||||
"path": _custom_plugins_path + "/vault.py",
|
||||
},
|
||||
{
|
||||
"name": "YandexDetector",
|
||||
"path": _custom_plugins_path + "/yandex.py",
|
||||
},
|
||||
{
|
||||
"name": "ZendeskSecretKeyDetector",
|
||||
"path": _custom_plugins_path + "/zendesk_secret_key.py",
|
||||
},
|
||||
{"name": "Base64HighEntropyString", "limit": 3.0},
|
||||
{"name": "HexHighEntropyString", "limit": 3.0},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
class _ENTERPRISE_SecretDetection(CustomLogger):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def scan_message_for_secrets(self, message_content: str):
|
||||
from detect_secrets import SecretsCollection
|
||||
from detect_secrets.settings import default_settings
|
||||
from detect_secrets.settings import transient_settings
|
||||
|
||||
temp_file = tempfile.NamedTemporaryFile(delete=False)
|
||||
temp_file.write(message_content.encode("utf-8"))
|
||||
temp_file.close()
|
||||
|
||||
secrets = SecretsCollection()
|
||||
with default_settings():
|
||||
with transient_settings(_default_detect_secrets_config):
|
||||
secrets.scan_file(temp_file.name)
|
||||
|
||||
os.remove(temp_file.name)
|
||||
|
||||
detected_secrets = []
|
||||
for file in secrets.files:
|
||||
|
||||
for found_secret in secrets[file]:
|
||||
|
||||
if found_secret.secret_value is None:
|
||||
continue
|
||||
detected_secrets.append(
|
||||
|
@ -76,6 +478,7 @@ class _ENTERPRISE_SecretDetection(CustomLogger):
|
|||
if "messages" in data and isinstance(data["messages"], list):
|
||||
for message in data["messages"]:
|
||||
if "content" in message and isinstance(message["content"], str):
|
||||
|
||||
detected_secrets = self.scan_message_for_secrets(message["content"])
|
||||
|
||||
for secret in detected_secrets:
|
||||
|
|
0
enterprise/enterprise_hooks/secrets_plugins/__init__.py
Normal file
0
enterprise/enterprise_hooks/secrets_plugins/__init__.py
Normal file
23
enterprise/enterprise_hooks/secrets_plugins/adafruit.py
Normal file
23
enterprise/enterprise_hooks/secrets_plugins/adafruit.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Adafruit keys
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AdafruitKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Adafruit keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Adafruit API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:adafruit)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/adobe.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/adobe.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for Adobe keys
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AdobeSecretDetector(RegexBasedDetector):
|
||||
"""Scans for Adobe client keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Adobe Client Keys"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Adobe Client ID (OAuth Web)
|
||||
re.compile(
|
||||
r"""(?i)(?:adobe)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Adobe Client Secret
|
||||
re.compile(r"(?i)\b((p8e-)[a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"),
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
This plugin searches for Age secret keys
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AgeSecretKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Age secret keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Age Secret Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(r"""AGE-SECRET-KEY-1[QPZRY9X8GF2TVDW0S3JN54KHCE6MUA7L]{58}"""),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Airtable API keys
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AirtableApiKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Airtable API keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Airtable API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:airtable)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{17})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
This plugin searches for Algolia API keys
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AlgoliaApiKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Algolia API keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Algolia API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(r"""(?i)\b((LTAI)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)"""),
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/alibaba.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/alibaba.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for Alibaba secrets
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AlibabaSecretDetector(RegexBasedDetector):
|
||||
"""Scans for Alibaba AccessKey IDs and Secret Keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Alibaba Secrets"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Alibaba AccessKey ID
|
||||
re.compile(r"""(?i)\b((LTAI)[a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)"""),
|
||||
# For Alibaba Secret Key
|
||||
re.compile(
|
||||
r"""(?i)(?:alibaba)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{30})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/asana.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/asana.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Asana secrets
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AsanaSecretDetector(RegexBasedDetector):
|
||||
"""Scans for Asana Client IDs and Client Secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Asana Secrets"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Asana Client ID
|
||||
re.compile(
|
||||
r"""(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# For Asana Client Secret
|
||||
re.compile(
|
||||
r"""(?i)(?:asana)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Atlassian API tokens
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AtlassianApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Atlassian API tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Atlassian API token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Atlassian API token
|
||||
re.compile(
|
||||
r"""(?i)(?:atlassian|confluence|jira)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Authress Service Client Access Keys
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class AuthressAccessKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Authress Service Client Access Keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Authress Service Client Access Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Authress Service Client Access Key
|
||||
re.compile(
|
||||
r"""(?i)\b((?:sc|ext|scauth|authress)_[a-z0-9]{5,30}\.[a-z0-9]{4,6}\.acc[_-][a-z0-9-]{10,32}\.[a-z0-9+/_=-]{30,120})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Beamer API tokens
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class BeamerApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Beamer API tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Beamer API token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Beamer API token
|
||||
re.compile(
|
||||
r"""(?i)(?:beamer)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(b_[a-z0-9=_\-]{44})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/bitbucket.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/bitbucket.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Bitbucket Client ID and Client Secret
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class BitbucketDetector(RegexBasedDetector):
|
||||
"""Scans for Bitbucket Client ID and Client Secret."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Bitbucket Secrets"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Bitbucket Client ID
|
||||
re.compile(
|
||||
r"""(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# For Bitbucket Client Secret
|
||||
re.compile(
|
||||
r"""(?i)(?:bitbucket)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/bittrex.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/bittrex.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Bittrex Access Key and Secret Key
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class BittrexDetector(RegexBasedDetector):
|
||||
"""Scans for Bittrex Access Key and Secret Key."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Bittrex Secrets"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Bittrex Access Key
|
||||
re.compile(
|
||||
r"""(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# For Bittrex Secret Key
|
||||
re.compile(
|
||||
r"""(?i)(?:bittrex)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
This plugin searches for Clojars API tokens
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class ClojarsApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Clojars API tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Clojars API token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Clojars API token
|
||||
re.compile(r"(?i)(CLOJARS_)[a-z0-9]{60}"),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Codecov Access Token
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class CodecovAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Codecov Access Token."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Codecov Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Codecov Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:codecov)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Coinbase Access Token
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class CoinbaseAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Coinbase Access Token."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Coinbase Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Coinbase Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:coinbase)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/confluent.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/confluent.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Confluent Access Token and Confluent Secret Key
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class ConfluentDetector(RegexBasedDetector):
|
||||
"""Scans for Confluent Access Token and Confluent Secret Key."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Confluent Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# For Confluent Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# For Confluent Secret Key
|
||||
re.compile(
|
||||
r"""(?i)(?:confluent)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Contentful delivery API token.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class ContentfulApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Contentful delivery API token."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Contentful API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:contentful)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
This plugin searches for Databricks API token.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DatabricksApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Databricks API token."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Databricks API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(r"""(?i)\b(dapi[a-h0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Datadog Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DatadogAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Datadog Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Datadog Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:datadog)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Defined Networking API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DefinedNetworkingApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Defined Networking API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Defined Networking API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:dnkey)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(dnkey-[a-z0-9=_\-]{26}-[a-z0-9=_\-]{52})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/digitalocean.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/digitalocean.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for DigitalOcean tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DigitaloceanDetector(RegexBasedDetector):
|
||||
"""Scans for various DigitalOcean Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "DigitalOcean Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# OAuth Access Token
|
||||
re.compile(r"""(?i)\b(doo_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""),
|
||||
# Personal Access Token
|
||||
re.compile(r"""(?i)\b(dop_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""),
|
||||
# OAuth Refresh Token
|
||||
re.compile(r"""(?i)\b(dor_v1_[a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""),
|
||||
]
|
32
enterprise/enterprise_hooks/secrets_plugins/discord.py
Normal file
32
enterprise/enterprise_hooks/secrets_plugins/discord.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
This plugin searches for Discord Client tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DiscordDetector(RegexBasedDetector):
|
||||
"""Scans for various Discord Client Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Discord Client Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Discord API key
|
||||
re.compile(
|
||||
r"""(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Discord client ID
|
||||
re.compile(
|
||||
r"""(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9]{18})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Discord client secret
|
||||
re.compile(
|
||||
r"""(?i)(?:discord)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
This plugin searches for Doppler API tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DopplerApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Doppler API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Doppler API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Doppler API token
|
||||
re.compile(r"""(?i)dp\.pt\.[a-z0-9]{43}"""),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Droneci Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DroneciAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Droneci Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Droneci Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Droneci Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:droneci)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
32
enterprise/enterprise_hooks/secrets_plugins/dropbox.py
Normal file
32
enterprise/enterprise_hooks/secrets_plugins/dropbox.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
This plugin searches for Dropbox tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DropboxDetector(RegexBasedDetector):
|
||||
"""Scans for various Dropbox Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Dropbox Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Dropbox API secret
|
||||
re.compile(
|
||||
r"""(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{15})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Dropbox long-lived API token
|
||||
re.compile(
|
||||
r"""(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{11}(AAAAAAAAAA)[a-z0-9\-_=]{43})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Dropbox short-lived API token
|
||||
re.compile(
|
||||
r"""(?i)(?:dropbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(sl\.[a-z0-9\-=_]{135})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
This plugin searches for Duffel API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DuffelApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Duffel API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Duffel API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Duffel API Token
|
||||
re.compile(r"""(?i)duffel_(test|live)_[a-z0-9_\-=]{43}"""),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
This plugin searches for Dynatrace API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class DynatraceApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Dynatrace API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Dynatrace API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Dynatrace API Token
|
||||
re.compile(r"""(?i)dt0c01\.[a-z0-9]{24}\.[a-z0-9]{64}"""),
|
||||
]
|
24
enterprise/enterprise_hooks/secrets_plugins/easypost.py
Normal file
24
enterprise/enterprise_hooks/secrets_plugins/easypost.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for EasyPost tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class EasyPostDetector(RegexBasedDetector):
|
||||
"""Scans for various EasyPost Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "EasyPost Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# EasyPost API token
|
||||
re.compile(r"""(?i)\bEZAK[a-z0-9]{54}"""),
|
||||
# EasyPost test API token
|
||||
re.compile(r"""(?i)\bEZTK[a-z0-9]{54}"""),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Etsy Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class EtsyAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Etsy Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Etsy Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Etsy Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:etsy)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Facebook Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FacebookAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Facebook Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Facebook Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Facebook Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:facebook)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Fastly API keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FastlyApiKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Fastly API keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Fastly API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Fastly API key
|
||||
re.compile(
|
||||
r"""(?i)(?:fastly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/finicity.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/finicity.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Finicity API tokens and Client Secrets.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FinicityDetector(RegexBasedDetector):
|
||||
"""Scans for Finicity API tokens and Client Secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Finicity Credentials"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Finicity API token
|
||||
re.compile(
|
||||
r"""(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Finicity Client Secret
|
||||
re.compile(
|
||||
r"""(?i)(?:finicity)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Finnhub Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FinnhubAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Finnhub Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Finnhub Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Finnhub Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:finnhub)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{20})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Flickr Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FlickrAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Flickr Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Flickr Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Flickr Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:flickr)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/flutterwave.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/flutterwave.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for Flutterwave API keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FlutterwaveDetector(RegexBasedDetector):
|
||||
"""Scans for Flutterwave API Keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Flutterwave API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Flutterwave Encryption Key
|
||||
re.compile(r"""(?i)FLWSECK_TEST-[a-h0-9]{12}"""),
|
||||
# Flutterwave Public Key
|
||||
re.compile(r"""(?i)FLWPUBK_TEST-[a-h0-9]{32}-X"""),
|
||||
# Flutterwave Secret Key
|
||||
re.compile(r"""(?i)FLWSECK_TEST-[a-h0-9]{32}-X"""),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
This plugin searches for Frame.io API tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FrameIoApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Frame.io API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Frame.io API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Frame.io API token
|
||||
re.compile(r"""(?i)fio-u-[a-z0-9\-_=]{64}"""),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Freshbooks Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class FreshbooksAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Freshbooks Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Freshbooks Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Freshbooks Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:freshbooks)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
24
enterprise/enterprise_hooks/secrets_plugins/gcp_api_key.py
Normal file
24
enterprise/enterprise_hooks/secrets_plugins/gcp_api_key.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for GCP API keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class GCPApiKeyDetector(RegexBasedDetector):
|
||||
"""Scans for GCP API keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "GCP API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# GCP API Key
|
||||
re.compile(
|
||||
r"""(?i)\b(AIza[0-9A-Za-z\\-_]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/github_token.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/github_token.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for GitHub tokens
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class GitHubTokenCustomDetector(RegexBasedDetector):
|
||||
"""Scans for GitHub tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "GitHub Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# GitHub App/Personal Access/OAuth Access/Refresh Token
|
||||
# ref. https://github.blog/2021-04-05-behind-githubs-new-authentication-token-formats/
|
||||
re.compile(r"(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36}"),
|
||||
# GitHub Fine-Grained Personal Access Token
|
||||
re.compile(r"github_pat_[0-9a-zA-Z_]{82}"),
|
||||
re.compile(r"gho_[0-9a-zA-Z]{36}"),
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/gitlab.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/gitlab.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for GitLab secrets.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class GitLabDetector(RegexBasedDetector):
|
||||
"""Scans for GitLab Secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "GitLab Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# GitLab Personal Access Token
|
||||
re.compile(r"""glpat-[0-9a-zA-Z\-\_]{20}"""),
|
||||
# GitLab Pipeline Trigger Token
|
||||
re.compile(r"""glptt-[0-9a-f]{40}"""),
|
||||
# GitLab Runner Registration Token
|
||||
re.compile(r"""GR1348941[0-9a-zA-Z\-\_]{20}"""),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Gitter Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class GitterAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Gitter Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Gitter Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Gitter Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:gitter)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
"""
|
||||
This plugin searches for GoCardless API tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class GoCardlessApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for GoCardless API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "GoCardless API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# GoCardless API token
|
||||
re.compile(
|
||||
r"""(?:gocardless)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(live_[a-z0-9\-_=]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)""",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
]
|
32
enterprise/enterprise_hooks/secrets_plugins/grafana.py
Normal file
32
enterprise/enterprise_hooks/secrets_plugins/grafana.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
This plugin searches for Grafana secrets.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class GrafanaDetector(RegexBasedDetector):
|
||||
"""Scans for Grafana Secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Grafana Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Grafana API key or Grafana Cloud API key
|
||||
re.compile(
|
||||
r"""(?i)\b(eyJrIjoi[A-Za-z0-9]{70,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Grafana Cloud API token
|
||||
re.compile(
|
||||
r"""(?i)\b(glc_[A-Za-z0-9+/]{32,400}={0,2})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Grafana Service Account token
|
||||
re.compile(
|
||||
r"""(?i)\b(glsa_[A-Za-z0-9]{32}_[A-Fa-f0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
"""
|
||||
This plugin searches for HashiCorp Terraform user/org API tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class HashiCorpTFApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for HashiCorp Terraform User/Org API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "HashiCorp Terraform API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# HashiCorp Terraform user/org API token
|
||||
re.compile(r"""(?i)[a-z0-9]{14}\.atlasv1\.[a-z0-9\-_=]{60,70}"""),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Heroku API Keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class HerokuApiKeyDetector(RegexBasedDetector):
|
||||
"""Scans for Heroku API Keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Heroku API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:heroku)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for HubSpot API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class HubSpotApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for HubSpot API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "HubSpot API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# HubSpot API Token
|
||||
re.compile(
|
||||
r"""(?i)(?:hubspot)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/huggingface.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/huggingface.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for Hugging Face Access and Organization API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class HuggingFaceDetector(RegexBasedDetector):
|
||||
"""Scans for Hugging Face Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Hugging Face Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Hugging Face Access token
|
||||
re.compile(r"""(?:^|[\\'"` >=:])(hf_[a-zA-Z]{34})(?:$|[\\'"` <])"""),
|
||||
# Hugging Face Organization API token
|
||||
re.compile(
|
||||
r"""(?:^|[\\'"` >=:\(,)])(api_org_[a-zA-Z]{34})(?:$|[\\'"` <\),])"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Intercom API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class IntercomApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Intercom API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Intercom API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:intercom)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{60})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/jfrog.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/jfrog.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for JFrog-related secrets like API Key and Identity Token.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class JFrogDetector(RegexBasedDetector):
|
||||
"""Scans for JFrog-related secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "JFrog Secrets"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# JFrog API Key
|
||||
re.compile(
|
||||
r"""(?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{73})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# JFrog Identity Token
|
||||
re.compile(
|
||||
r"""(?i)(?:jfrog|artifactory|bintray|xray)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
24
enterprise/enterprise_hooks/secrets_plugins/jwt.py
Normal file
24
enterprise/enterprise_hooks/secrets_plugins/jwt.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Base64-encoded JSON Web Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class JWTBase64Detector(RegexBasedDetector):
|
||||
"""Scans for Base64-encoded JSON Web Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Base64-encoded JSON Web Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Base64-encoded JSON Web Token
|
||||
re.compile(
|
||||
r"""\bZXlK(?:(?P<alg>aGJHY2lPaU)|(?P<apu>aGNIVWlPaU)|(?P<apv>aGNIWWlPaU)|(?P<aud>aGRXUWlPaU)|(?P<b64>aU5qUWlP)|(?P<crit>amNtbDBJanBi)|(?P<cty>amRIa2lPaU)|(?P<epk>bGNHc2lPbn)|(?P<enc>bGJtTWlPaU)|(?P<jku>cWEzVWlPaU)|(?P<jwk>cWQyc2lPb)|(?P<iss>cGMzTWlPaU)|(?P<iv>cGRpSTZJ)|(?P<kid>cmFXUWlP)|(?P<key_ops>clpYbGZiM0J6SWpwY)|(?P<kty>cmRIa2lPaUp)|(?P<nonce>dWIyNWpaU0k2)|(?P<p2c>d01tTWlP)|(?P<p2s>d01uTWlPaU)|(?P<ppt>d2NIUWlPaU)|(?P<sub>emRXSWlPaU)|(?P<svt>emRuUWlP)|(?P<tag>MFlXY2lPaU)|(?P<typ>MGVYQWlPaUp)|(?P<url>MWNtd2l)|(?P<use>MWMyVWlPaUp)|(?P<ver>MlpYSWlPaU)|(?P<version>MlpYSnphVzl1SWpv)|(?P<x>NElqb2)|(?P<x5c>NE5XTWlP)|(?P<x5t>NE5YUWlPaU)|(?P<x5ts256>NE5YUWpVekkxTmlJNkl)|(?P<x5u>NE5YVWlPaU)|(?P<zip>NmFYQWlPaU))[a-zA-Z0-9\/\\_+\-\r\n]{40,}={0,2}"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Kraken Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class KrakenAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Kraken Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Kraken Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Kraken Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:kraken)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9\/=_\+\-]{80,90})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/kucoin.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/kucoin.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Kucoin Access Tokens and Secret Keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class KucoinDetector(RegexBasedDetector):
|
||||
"""Scans for Kucoin Access Tokens and Secret Keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Kucoin Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Kucoin Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{24})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Kucoin Secret Key
|
||||
re.compile(
|
||||
r"""(?i)(?:kucoin)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Launchdarkly Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class LaunchdarklyAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Launchdarkly Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Launchdarkly Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:launchdarkly)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
26
enterprise/enterprise_hooks/secrets_plugins/linear.py
Normal file
26
enterprise/enterprise_hooks/secrets_plugins/linear.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This plugin searches for Linear API Tokens and Linear Client Secrets.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class LinearDetector(RegexBasedDetector):
|
||||
"""Scans for Linear secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Linear Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Linear API Token
|
||||
re.compile(r"""(?i)lin_api_[a-z0-9]{40}"""),
|
||||
# Linear Client Secret
|
||||
re.compile(
|
||||
r"""(?i)(?:linear)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/linkedin.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/linkedin.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for LinkedIn Client IDs and LinkedIn Client secrets.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class LinkedInDetector(RegexBasedDetector):
|
||||
"""Scans for LinkedIn secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "LinkedIn Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# LinkedIn Client ID
|
||||
re.compile(
|
||||
r"""(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{14})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# LinkedIn Client secret
|
||||
re.compile(
|
||||
r"""(?i)(?:linkedin|linked-in)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/lob.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/lob.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Lob API secrets and Lob Publishable API keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class LobDetector(RegexBasedDetector):
|
||||
"""Scans for Lob secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Lob Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Lob API Key
|
||||
re.compile(
|
||||
r"""(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((live|test)_[a-f0-9]{35})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Lob Publishable API Key
|
||||
re.compile(
|
||||
r"""(?i)(?:lob)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}((test|live)_pub_[a-f0-9]{31})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
32
enterprise/enterprise_hooks/secrets_plugins/mailgun.py
Normal file
32
enterprise/enterprise_hooks/secrets_plugins/mailgun.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
This plugin searches for Mailgun API secrets, public validation keys, and webhook signing keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class MailgunDetector(RegexBasedDetector):
|
||||
"""Scans for Mailgun secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Mailgun Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Mailgun Private API Token
|
||||
re.compile(
|
||||
r"""(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(key-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Mailgun Public Validation Key
|
||||
re.compile(
|
||||
r"""(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pubkey-[a-f0-9]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Mailgun Webhook Signing Key
|
||||
re.compile(
|
||||
r"""(?i)(?:mailgun)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-h0-9]{32}-[a-h0-9]{8}-[a-h0-9]{8})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for MapBox API tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class MapBoxApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for MapBox API tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "MapBox API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# MapBox API Token
|
||||
re.compile(
|
||||
r"""(?i)(?:mapbox)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(pk\.[a-z0-9]{60}\.[a-z0-9]{22})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Mattermost Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class MattermostAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Mattermost Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Mattermost Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Mattermost Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:mattermost)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{26})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
28
enterprise/enterprise_hooks/secrets_plugins/messagebird.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/messagebird.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for MessageBird API tokens and client IDs.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class MessageBirdDetector(RegexBasedDetector):
|
||||
"""Scans for MessageBird secrets."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "MessageBird Secret"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# MessageBird API Token
|
||||
re.compile(
|
||||
r"""(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{25})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# MessageBird Client ID
|
||||
re.compile(
|
||||
r"""(?i)(?:messagebird|message-bird|message_bird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Microsoft Teams Webhook URLs.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class MicrosoftTeamsWebhookDetector(RegexBasedDetector):
|
||||
"""Scans for Microsoft Teams Webhook URLs."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Microsoft Teams Webhook"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Microsoft Teams Webhook
|
||||
re.compile(
|
||||
r"""https:\/\/[a-z0-9]+\.webhook\.office\.com\/webhookb2\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}@[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}\/IncomingWebhook\/[a-z0-9]{32}\/[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
"""
|
||||
This plugin searches for Netlify Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class NetlifyAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Netlify Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Netlify Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Netlify Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:netlify)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{40,46})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
32
enterprise/enterprise_hooks/secrets_plugins/new_relic.py
Normal file
32
enterprise/enterprise_hooks/secrets_plugins/new_relic.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
This plugin searches for New Relic API tokens and keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class NewRelicDetector(RegexBasedDetector):
|
||||
"""Scans for New Relic API tokens and keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "New Relic API Secrets"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# New Relic ingest browser API token
|
||||
re.compile(
|
||||
r"""(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRJS-[a-f0-9]{19})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# New Relic user API ID
|
||||
re.compile(
|
||||
r"""(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# New Relic user API Key
|
||||
re.compile(
|
||||
r"""(?i)(?:new-relic|newrelic|new_relic)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}(NRAK-[a-z0-9]{27})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for New York Times Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class NYTimesAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for New York Times Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "New York Times Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:nytimes|new-york-times,|newyorktimes)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{32})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Okta Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class OktaAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Okta Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Okta Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:okta)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9=_\-]{42})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
This plugin searches for OpenAI API Keys.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class OpenAIApiKeyDetector(RegexBasedDetector):
|
||||
"""Scans for OpenAI API Keys."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Strict OpenAI API Key"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [re.compile(r"""(sk-[a-zA-Z0-9]{5,})""")]
|
32
enterprise/enterprise_hooks/secrets_plugins/planetscale.py
Normal file
32
enterprise/enterprise_hooks/secrets_plugins/planetscale.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
"""
|
||||
This plugin searches for PlanetScale API tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class PlanetScaleDetector(RegexBasedDetector):
|
||||
"""Scans for PlanetScale API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "PlanetScale API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# the PlanetScale API token
|
||||
re.compile(
|
||||
r"""(?i)\b(pscale_tkn_[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# the PlanetScale OAuth token
|
||||
re.compile(
|
||||
r"""(?i)\b(pscale_oauth_[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# the PlanetScale password
|
||||
re.compile(
|
||||
r"""(?i)\b(pscale_pw_[a-z0-9=\-_\.]{32,64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Postman API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class PostmanApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Postman API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Postman API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)\b(PMAK-[a-f0-9]{24}-[a-f0-9]{34})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
This plugin searches for Prefect API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class PrefectApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Prefect API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Prefect API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [re.compile(r"""(?i)\b(pnu_[a-z0-9]{36})(?:['|\"|\n|\r|\s|\x60|;]|$)""")]
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
This plugin searches for Pulumi API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class PulumiApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Pulumi API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Pulumi API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [re.compile(r"""(?i)\b(pul-[a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)""")]
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
This plugin searches for PyPI Upload Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class PyPiUploadTokenDetector(RegexBasedDetector):
|
||||
"""Scans for PyPI Upload Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "PyPI Upload Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [re.compile(r"""pypi-AgEIcHlwaS5vcmc[A-Za-z0-9\-_]{50,1000}""")]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for RapidAPI Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class RapidApiAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for RapidAPI Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "RapidAPI Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:rapidapi)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-z0-9_-]{50})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
This plugin searches for Readme API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class ReadmeApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Readme API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Readme API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(r"""(?i)\b(rdme_[a-z0-9]{70})(?:['|\"|\n|\r|\s|\x60|;]|$)""")
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
"""
|
||||
This plugin searches for Rubygem API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class RubygemsApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Rubygem API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Rubygem API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(r"""(?i)\b(rubygems_[a-f0-9]{48})(?:['|\"|\n|\r|\s|\x60|;]|$)""")
|
||||
]
|
|
@ -0,0 +1,19 @@
|
|||
"""
|
||||
This plugin searches for Scalingo API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class ScalingoApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Scalingo API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Scalingo API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [re.compile(r"""\btk-us-[a-zA-Z0-9-_]{48}\b""")]
|
28
enterprise/enterprise_hooks/secrets_plugins/sendbird.py
Normal file
28
enterprise/enterprise_hooks/secrets_plugins/sendbird.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
This plugin searches for Sendbird Access IDs and Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class SendbirdDetector(RegexBasedDetector):
|
||||
"""Scans for Sendbird Access IDs and Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Sendbird Credential"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
# Sendbird Access ID
|
||||
re.compile(
|
||||
r"""(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
# Sendbird Access Token
|
||||
re.compile(
|
||||
r"""(?i)(?:sendbird)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{40})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for SendGrid API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class SendGridApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for SendGrid API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "SendGrid API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)\b(SG\.[a-z0-9=_\-\.]{66})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for SendinBlue API Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class SendinBlueApiTokenDetector(RegexBasedDetector):
|
||||
"""Scans for SendinBlue API Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "SendinBlue API Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)\b(xkeysib-[a-f0-9]{64}-[a-z0-9]{16})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
"""
|
||||
This plugin searches for Sentry Access Tokens.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from detect_secrets.plugins.base import RegexBasedDetector
|
||||
|
||||
|
||||
class SentryAccessTokenDetector(RegexBasedDetector):
|
||||
"""Scans for Sentry Access Tokens."""
|
||||
|
||||
@property
|
||||
def secret_type(self) -> str:
|
||||
return "Sentry Access Token"
|
||||
|
||||
@property
|
||||
def denylist(self) -> list[re.Pattern]:
|
||||
return [
|
||||
re.compile(
|
||||
r"""(?i)(?:sentry)(?:[0-9a-z\-_\t .]{0,20})(?:[\s|']|[\s|"]){0,3}(?:=|>|:{1,3}=|\|\|:|<=|=>|:|\?=)(?:'|\"|\s|=|\x60){0,5}([a-f0-9]{64})(?:['|\"|\n|\r|\s|\x60|;]|$)"""
|
||||
)
|
||||
]
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue