# **Github Secrets and SecretScanning**
### **About secrets:**
- Secrets are variables that you create in an organization, repository, or repository environment. The secrets that you create are available to use in GitHub Actions workflows. GitHub Actions can only read a secret if you explicitly include the secret in a workflow.
- For secrets stored at the organization-level, you can use access policies to control which repositories can use organization secrets. Organization-level secrets let you share secrets between multiple repositories, which reduces the need for creating duplicate secrets. Updating an organization secret in one location also ensures that the change takes effect in all repository workflows that use that secret.
- For secrets stored at the environment level, you can enable required reviewers to control access to the secrets. A workflow job cannot access environment secrets until approval is granted by required approvers.
### **Limits for secrets:**
- You can store up to 1,000 organization secrets, 100 repository secrets, and 100 environment secrets.
- A workflow created in a repository can access the following number of secrets:
- All 100 repository secrets.
- If the repository is assigned access to more than 100 organization secrets, the workflow can only use the first 100 organization secrets (sorted alphabetically by secret name).
- All 100 environment secrets.
- Secrets are limited to 48 KB in size.
### **About secrets in GitHub Actions**
- You can use the REST API to create, update, delete, and retrieve information about encrypted secrets that can be used in workflows in GitHub Actions. Encrypted secrets allow you to store sensitive information, such as access tokens, in your repository, repository environments, or organization.
> The personal access token that we will be using throughout the POC will have the following permissions:
> 
### **Store Repository Secrets in GitHub**
1. [List repository secrets](https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#list-repository-secrets)
- Lists all secrets available in a repository without revealing their encrypted values. You must authenticate using an access token with the `repo` scope to use this endpoint.
- **API:** **GET** `/repos/{owner}/{repo}/actions/secrets`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/actions/secrets`

1. [Get a repository public key](https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-a-repository-public-key)
- Gets your public key, which you need to encrypt secrets. You need to encrypt a secret before you can create or update secrets. Anyone with read access to the repository can use this endpoint. If the repository is private you must use an access token with the `repo` scope.
- **API:** **GET** `/repos/{owner}/{repo}/actions/secrets/public-key`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/actions/secrets/public-key`

1. [Get a repository secret](https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#get-a-repository-secret)
- Gets a single repository secret without revealing its encrypted value. You must authenticate using an access token with the `repo` scope to use this endpoint.
- **API:** **GET** `/repos/{owner}/{repo}/actions/secrets/{secret_name}`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/actions/secrets/SECRET_NAME`

1. [Create or update a repository secret](https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#create-or-update-a-repository-secret)
- Creates or updates a repository secret with an encrypted value. Encrypt your secret using **LibSodium**. We use the **PyNaCl** library in python to encrypt our secret.
```python=
from base64 import b64encode
from nacl import encoding, public
def encrypt(public_key: str, secret_value: str) -> str:
"""Encrypt a Unicode string using the public key."""
public_key = public.PublicKey(public_key.encode("utf-8"), encoding.Base64Encoder())
sealed_box = public.SealedBox(public_key)
encrypted = sealed_box.encrypt(secret_value.encode("utf-8"))
return b64encode(encrypted).decode("utf-8")
```

- The API for creating/updating the secret is:
- **API:** **PUT** `/repos/{owner}/{repo}/actions/secrets/{secret_name}`
- **Headers:** `Accept: application/vnd.github+json`,`Authorization: Bearer <YOUR-TOKEN>`,`X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/actions/secrets/SECRET_NAME`
- **Body:** `{"encrypted_value":"<YOUR_ENCRYPTED_VALUE>","key_id":"<YOUR_KEY_ID>"}`. The `encrypted_value` string is the Value for your secret, encrypted with LibSodium using the public key retrieved from the Get a repository public key endpoint. And the `key_id` string is the ID of the key you used to encrypt the secret.

- We can see in GitHub repo that our secret has been successfully created: 
5. [Delete a repository secret](https://docs.github.com/en/rest/actions/secrets?apiVersion=2022-11-28#delete-a-repository-secret)
- Deletes a secret in a repository using the secret name. You must authenticate using an access token with the `repo` scope to use this endpoint.
- **API:** **DELETE** `/repos/{owner}/{repo}/actions/secrets/{secret_name}`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/actions/secrets/SECRET_NAME`

- We have successfully deleted the Secret: 
### **About Secret Scanning in a GitHub Repository**
GitHub scans repositories for known types of secrets, to prevent fraudulent use of secrets that were committed accidentally. Secret scanning scans the entire Git history on all branches present in a GitHub repository for secrets.
Any strings that match patterns provided by secret scanning partners, by other service providers, or defined by the organization, are reported as alerts in the Security tab of repositories. If a string in a public repository matches a partner pattern, it is also reported to the partner.
Secret scanning alerts for users are available for free on all public repositories. When enabled, GitHub scans the code for patterns that match secrets used by many service providers. When the scan is completed, GitHub sends an email alert to the enterprise and organization owners, even if no secrets were found.
When a supported secret is leaked, GitHub generates a secret scanning alert. GitHub will also periodically run a full git history scan of existing content in public repositories where secret scanning is enabled, and send alert notifications following the secret scanning alert notification settings.
We can also define custom secret scanning patterns for a repository, organization, or enterprise. But for this, we need GitHub Enterprise Cloud Account.
We can also use the REST API to enable and monitor results from secret scanning across repositories. The API endpoints for the same are mentioned in the next section of the document.
Here is the link to all the supported secrets that can be identified using secret scanning: [Secret_Scanning_Patterns](https://docs.github.com/en/code-security/secret-scanning/secret-scanning-patterns)
### **Enable Secret Scanning in a GitHub Repository**
We use the `Update a repository` API to enable secret scanning.
- **API:** **PATCH** `/repos/{owner}/{repo}`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO`
- **Body:** `{"security_and_analysis": {"advanced_security": {"secret_scanning": {"status": "enabled"}}}`

### **Monitoring Secret Scanning results**
1. [List secret scanning alerts for a repository](https://docs.github.com/en/rest/secret-scanning/secret-scanning?apiVersion=2022-11-28#list-secret-scanning-alerts-for-a-repository)
- Lists all secret scanning alerts for an eligible repository, from newest to oldest.
- **API:** **GET** `/repos/{owner}/{repo}/secret-scanning/alerts`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/secret-scanning/alerts`

1. [Get a secret scanning alert](https://docs.github.com/en/rest/secret-scanning/secret-scanning?apiVersion=2022-11-28#get-a-secret-scanning-alert)
- Gets a single secret scanning alert detected in an eligible repository.
- **API:** **GET** `/repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/secret-scanning/alerts/ALERT_NUMBER`

1. [Update a secret scanning alert](https://docs.github.com/en/rest/secret-scanning/secret-scanning?apiVersion=2022-11-28#update-a-secret-scanning-alert)
- Updates the status of a secret scanning alert in an eligible repository.
- **API:** **PATCH** `/repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}`
- **Headers:** `Accept: application/vnd.github+json`, `Authorization: Bearer <YOUR-TOKEN>`, `X-GitHub-Api-Version: 2022-11-28`
- **URL:** `https://api.github.com/repos/OWNER/REPO/secret-scanning/alerts/ALERT_NUMBER`
- **Body:** `{"state":"resolved","resolution":"false_positive"}`. Here is the description for the Body parameters:
- `state` (string) (Required), Sets the state of the secret scanning alert. You must provide `resolution` when you set the `state` to resolved. Can be one of: `open`, `resolved`.
- `resolution` (string or null) (Required when the `state` is `resolved`). It is the reason for resolving the alert. Can be one of: `false_positive`, `wont_fix`, `revoked`, `used_in_tests`, `null`
- `resolution_comment` (string or null) An optional comment when closing an alert. Cannot be updated or deleted. Must be `null` when changing `state` to `open`.
> Now for the POC, I have revoked the secret from Postman, and now we will update its state using the above api as **Resolved** with the **revoked** resolution.

### **What happens when a vulnerability is found in secret scanning**
- For the POC, I deliberately added a Postman Collection Key as comment in the code. 
- The leaked secret shows up in the Secret Scanning Alerts page on the Security Tab in the Repository. 
- The user is alerted through mail that the secret is leaked in a commit. 
- Even Postman notifies the user about the leaked secret. 
- Here is the description that GitHub provides for the secret leak: 
- Now, after we updated its state as resolved under the revoked resolution, the UI on GitHub shows the following for the Secret Leak: 
- Here is the complete description for the same: 
---
## Difference between the GitHub Free and Enterprise versions
With GitHub Enterprise, Secret scanning will scan the entire Git history on all branches present in the GitHub repository for secrets, even if the repository is archived. It also scans the titles, descriptions, and comments in issues.
We can also define custom secret scanning patterns for a repository, organization, or enterprise. We can extend secret scanning to detect secrets beyond the default patterns. For example, there might be a secret pattern that is internal to the organization. We can define custom patterns for our enterprise, organization, or repository.
Secret scanning supports up to 500 custom patterns for each organization or enterprise account and up to 100 custom patterns per repository. We can specify custom patterns for secret scanning as one or more regular expressions. For more information visit thie link: [Custom Secret Patterns](https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/defining-custom-patterns-for-secret-scanning).
---