Skip to content

Commit 45c84d4

Browse files
committed
Merge branch 'main' into ENG-2705
2 parents 8e8e2e0 + 0d2b3ad commit 45c84d4

22 files changed

+197
-19
lines changed

backend/src/ee/routes/v1/secret-scanning-router.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { z } from "zod";
22

33
import { GitAppOrgSchema, SecretScanningGitRisksSchema } from "@app/db/schemas";
4+
import { canUseSecretScanning } from "@app/ee/services/secret-scanning/secret-scanning-fns";
45
import {
56
SecretScanningResolvedStatus,
67
SecretScanningRiskStatus
78
} from "@app/ee/services/secret-scanning/secret-scanning-types";
8-
import { getConfig } from "@app/lib/config/env";
99
import { BadRequestError } from "@app/lib/errors";
1010
import { OrderByDirection } from "@app/lib/types";
1111
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
@@ -23,14 +23,14 @@ export const registerSecretScanningRouter = async (server: FastifyZodProvider) =
2323
body: z.object({ organizationId: z.string().trim() }),
2424
response: {
2525
200: z.object({
26-
sessionId: z.string()
26+
sessionId: z.string(),
27+
gitAppSlug: z.string()
2728
})
2829
}
2930
},
3031
onRequest: verifyAuth([AuthMode.JWT]),
3132
handler: async (req) => {
32-
const appCfg = getConfig();
33-
if (!appCfg.SECRET_SCANNING_ORG_WHITELIST?.includes(req.auth.orgId)) {
33+
if (!canUseSecretScanning(req.auth.orgId)) {
3434
throw new BadRequestError({
3535
message: "Secret scanning is temporarily unavailable."
3636
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { getConfig } from "@app/lib/config/env";
2+
3+
export const canUseSecretScanning = (orgId: string) => {
4+
const appCfg = getConfig();
5+
6+
if (!appCfg.isCloud) {
7+
return true;
8+
}
9+
10+
return appCfg.SECRET_SCANNING_ORG_WHITELIST?.includes(orgId);
11+
};

backend/src/ee/services/secret-scanning/secret-scanning-service.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { NotFoundError } from "@app/lib/errors";
1212
import { TGitAppDALFactory } from "./git-app-dal";
1313
import { TGitAppInstallSessionDALFactory } from "./git-app-install-session-dal";
1414
import { TSecretScanningDALFactory } from "./secret-scanning-dal";
15+
import { canUseSecretScanning } from "./secret-scanning-fns";
1516
import { TSecretScanningQueueFactory } from "./secret-scanning-queue";
1617
import {
1718
SecretScanningRiskStatus,
@@ -47,12 +48,14 @@ export const secretScanningServiceFactory = ({
4748
actorAuthMethod,
4849
actorOrgId
4950
}: TInstallAppSessionDTO) => {
51+
const appCfg = getConfig();
52+
5053
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
5154
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning);
5255

5356
const sessionId = crypto.randomBytes(16).toString("hex");
5457
await gitAppInstallSessionDAL.upsert({ orgId, sessionId, userId: actorId });
55-
return { sessionId };
58+
return { sessionId, gitAppSlug: appCfg.SECRET_SCANNING_GIT_APP_SLUG };
5659
};
5760

5861
const linkInstallationToOrg = async ({
@@ -91,7 +94,8 @@ export const secretScanningServiceFactory = ({
9194
const {
9295
data: { repositories }
9396
} = await octokit.apps.listReposAccessibleToInstallation();
94-
if (appCfg.SECRET_SCANNING_ORG_WHITELIST?.includes(actorOrgId)) {
97+
98+
if (canUseSecretScanning(actorOrgId)) {
9599
await Promise.all(
96100
repositories.map(({ id, full_name }) =>
97101
secretScanningQueue.startFullRepoScan({
@@ -102,6 +106,7 @@ export const secretScanningServiceFactory = ({
102106
)
103107
);
104108
}
109+
105110
return { installatedApp };
106111
};
107112

@@ -164,7 +169,6 @@ export const secretScanningServiceFactory = ({
164169
};
165170

166171
const handleRepoPushEvent = async (payload: WebhookEventMap["push"]) => {
167-
const appCfg = getConfig();
168172
const { commits, repository, installation, pusher } = payload;
169173
if (!commits || !repository || !installation || !pusher) {
170174
return;
@@ -175,7 +179,7 @@ export const secretScanningServiceFactory = ({
175179
});
176180
if (!installationLink) return;
177181

178-
if (appCfg.SECRET_SCANNING_ORG_WHITELIST?.includes(installationLink.orgId)) {
182+
if (canUseSecretScanning(installationLink.orgId)) {
179183
await secretScanningQueue.startPushEventScan({
180184
commits,
181185
pusher: { name: pusher.name, email: pusher.email },

backend/src/lib/config/env.ts

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ const envSchema = z
146146
SECRET_SCANNING_GIT_APP_ID: zpStr(z.string().optional()),
147147
SECRET_SCANNING_PRIVATE_KEY: zpStr(z.string().optional()),
148148
SECRET_SCANNING_ORG_WHITELIST: zpStr(z.string().optional()),
149+
SECRET_SCANNING_GIT_APP_SLUG: zpStr(z.string().default("infisical-radar")),
149150
// LICENSE
150151
LICENSE_SERVER_URL: zpStr(z.string().optional().default("https://portal.infisical.com")),
151152
LICENSE_SERVER_KEY: zpStr(z.string().optional()),

docs/documentation/platform/secret-scanning.mdx

+107
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,113 @@ The Infisical Secret Scanner allows you to keep an overview and stay alert of ex
77

88
To further enhance security, we recommend you also use our [CLI Secret Scanner](/cli/scanning-overview#automatically-scan-changes-before-you-commit) to scan for exposed secrets prior to pushing your changes.
99

10+
11+
<Accordion title="Self-hosting">
12+
13+
To setup secret scanning on your own instance of Infisical, you can follow the steps below.
14+
15+
<Steps>
16+
<Step title="Create a GitHub App">
17+
Create a new GitHub app in your GitHub organization or personal [Developer Settings](https://github.com/settings/apps).
18+
19+
![Create GitHub App](/images/platform/secret-scanning/github-create-app.png)
20+
21+
### Configure the GitHub App
22+
To configure the GitHub app to work with Infisical, you'll need to modify the following settings:
23+
- **Homepage URL**: Required to be set. Set it to the URL of your Infisical instance. (e.g. `https://app.infisical.com`)
24+
- **Setup URL**: Set this to `https://<your-infisical-instance.com>/organization/secret-scanning`
25+
- **Webhook URL**: Set this to `https://<your-infisical-instance.com>/api/v1/secret-scanning/webhook`
26+
- **Webhook Secret**: Set this to a random string. This is used to verify the webhook request from Infisical. Use `openssl rand -base64 32` in your terminal to generate a random secret.
27+
28+
<Note>
29+
Remember to save the webhook secret as you will need it in the next step.
30+
</Note>
31+
32+
![GitHub App Settings](/images/platform/secret-scanning/github-configure-app.png)
33+
34+
### Configure the GitHub App Permissions
35+
The GitHub app needs the following permissions:
36+
37+
Repository permissions:
38+
- `Checks`: Read and Write
39+
- `Contents`: Read-only
40+
- `Issues`: Read and Write
41+
- `Pull Requests`: Read and Write
42+
- `Metadata`: Read-only (enabled by default)
43+
44+
![Github App Repository Permissions](/images/platform/secret-scanning/github-repo-permissions.png)
45+
46+
Subscribed events:
47+
- `Check run`
48+
- `Pull request`
49+
- `Push`
50+
51+
![Github App Subscribed Events](/images/platform/secret-scanning/github-subscribed-events.png)
52+
53+
54+
### Create the GitHub App
55+
Now you can create the GitHub app by clicking on the "Create GitHub App" button.
56+
57+
<Note>
58+
If you want other Github users to be able to install the app, you need to tick the "Any account" option under "Where can this GitHub App be installed?"
59+
</Note>
60+
61+
![Create GitHub App](/images/platform/secret-scanning/github-create-app-button.png)
62+
</Step>
63+
64+
<Step title="Retrieve the GitHub App ID">
65+
After clicking the "Create GitHub App" button, you will be redirected to the GitHub settings page. Here you can copy the "App ID" and save it for later when you need to configure your environment variables for your Infisical instance.
66+
67+
![Github App ID](/images/platform/secret-scanning/github-app-copy-app-id.png)
68+
</Step>
69+
70+
<Step title="Retrieve your GitHub App slug">
71+
The GitHub App slug is the name of the app you created in a slug friendly format. You can find the slug in the URL of the app you created.
72+
73+
![Github App Slug](/images/platform/secret-scanning/github-app-copy-slug.png)
74+
</Step>
75+
76+
<Step title="Create a new GitHub App private key">
77+
Create a new app private key by clicking on the "Generate a private key" button under the "Private keys" section.
78+
79+
Once you click the "Generate a private key" button, the private key will be downloaded to your computer. Save this file for later as you will need the private key when configuring Infisical.
80+
81+
![Github App Private Key](/images/platform/secret-scanning/github-app-create-private-key.png)
82+
83+
<Note>
84+
Remember to save the private key as you will need it in the next step.
85+
</Note>
86+
87+
</Step>
88+
89+
90+
<Step title="Configure your Infisical instance">
91+
Now you can configure your Infisical instance by setting the following environment variables:
92+
93+
- `SECRET_SCANNING_GIT_APP_ID`: The App ID of your GitHub App.
94+
- `SECRET_SCANNING_GIT_APP_SLUG`: The slug of your GitHub App.
95+
- `SECRET_SCANNING_PRIVATE_KEY`: The private key of your GitHub App that you created in a previous step.
96+
- `SECRET_SCANNING_WEBHOOK_SECRET`: The webhook secret of your GitHub App that you created in a previous step.
97+
</Step>
98+
</Steps>
99+
100+
After restarting your Infisical instance, you should be able to use the secret scanning feature within your organization. Follow the steps below to add the GitHub App to your Infisical organization.
101+
</Accordion>
102+
103+
## Install the Infisical Radar GitHub App
104+
105+
To install the GitHub App, press the "Integrate With GitHub" button in the top right corner of your Infisical Secret Scanning dashboard.
106+
107+
![Integrate With GitHub](/images/platform/secret-scanning/infisical-connect-secret-scanner.png)
108+
109+
Next, you'll be prompted to select which organization you'd like to install the app into. Select the organization you'd like to install the app into by clicking the organization in the menu.
110+
111+
![Select Organization](/images/platform/secret-scanning/github-select-org-2.png)
112+
113+
Select the repositories you'd like to scan for secrets and press the "Install" button.
114+
115+
![Select Repositories](/images/platform/secret-scanning/github-select-repos.png)
116+
10117
## Code Scanning
11118

12119
![Scanning Overview](/images/platform/secret-scanning/overview.png)
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

docs/internals/bug-bounty.mdx

+22-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ All final reward amounts are determined at Infisical's discretion based on impac
4141

4242
### Out of Scope
4343

44-
- Social engineering or phishing
44+
- Social engineering or phishing (including email hyperlink injection without code execution)
4545
- Rate limiting issues on non-sensitive endpoints
4646
- Denial-of-service attacks that require authentication and don't impact core service availability
4747
- Findings based on outdated or forked code not maintained by the Infisical team
@@ -57,4 +57,24 @@ We ask that researchers:
5757
- Use testing accounts where possible
5858
- Give us a reasonable window to investigate and patch before going public
5959

60-
Researchers can also spin up our [self-hosted version of Infisical](/self-hosting/overview) to test for vulnerabilities locally.
60+
Researchers can also spin up our [self-hosted version of Infisical](/self-hosting/overview) to test for vulnerabilities locally.
61+
62+
### Program Conduct and Enforcement
63+
64+
We value professional and collaborative interaction with security researchers. To maintain the integrity of our bug bounty program, we expect all participants to adhere to the following guidelines:
65+
66+
- Maintain professional communication in all interactions
67+
- Do not threaten public disclosure of vulnerabilities before we've had reasonable time to investigate and address the issue
68+
- Do not attempt to extort or coerce compensation through threats
69+
- Follow the responsible disclosure process outlined in this document
70+
- Do not use automated scanning tools without prior permission
71+
72+
Violations of these guidelines may result in:
73+
74+
1. **Warning**: For minor violations, we may issue a warning explaining the violation and requesting compliance with program guidelines.
75+
2. **Temporary Ban**: Repeated minor violations or more serious violations may result in a temporary suspension from the program.
76+
3. **Permanent Ban**: Severe violations such as threats, extortion attempts, or unauthorized public disclosure will result in permanent removal from the Infisical Bug Bounty Program.
77+
78+
We reserve the right to reject reports, withhold bounties, and remove participants from the program at our discretion for conduct that undermines the collaborative spirit of security research.
79+
80+
Infisical is committed to working respectfully with security researchers who follow these guidelines, and we strive to recognize and reward valuable contributions that help protect our platform and users.

docs/self-hosting/configuration/envars.mdx

+33
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ Used to configure platform-specific security and operational settings
2929
Specifies the internal port on which the application listens.
3030
</ParamField>
3131

32+
<ParamField query="HOST" type="string" default="localhost" optional>
33+
Specifies the network interface Infisical will bind to when accepting incoming connections.
34+
35+
By default, Infisical binds to `localhost`, which restricts access to connections from the same machine.
36+
37+
To make the application accessible externally (e.g., for self-hosted deployments), set this to `0.0.0.0`, which tells the server to listen on all network interfaces.
38+
39+
Example values:
40+
- `localhost` (default, same as `127.0.0.1`)
41+
- `0.0.0.0` (all interfaces, accessible externally)
42+
- `192.168.1.100` (specific interface IP)
43+
</ParamField>
44+
3245
<ParamField query="TELEMETRY_ENABLED" type="string" default="true" optional>
3346
Telemetry helps us improve Infisical but if you want to disable it you may set
3447
this to `false`.
@@ -612,6 +625,26 @@ To help you sync secrets from Infisical to services such as Github and Gitlab, I
612625
</ParamField>
613626
</Accordion>
614627

628+
## Secret Scanning
629+
630+
<Accordion title="GitHub">
631+
<ParamField query="SECRET_SCANNING_GIT_APP_ID" type="string" default="none" optional>
632+
The App ID of your GitHub App.
633+
</ParamField>
634+
635+
<ParamField query="SECRET_SCANNING_GIT_APP_SLUG" type="string" default="none" optional>
636+
The slug of your GitHub App.
637+
</ParamField>
638+
639+
<ParamField query="SECRET_SCANNING_PRIVATE_KEY" type="string" default="none" optional>
640+
A private key for your GitHub App.
641+
</ParamField>
642+
643+
<ParamField query="SECRET_SCANNING_WEBHOOK_SECRET" type="string" default="none" optional>
644+
The webhook secret of your GitHub App.
645+
</ParamField>
646+
</Accordion>
647+
615648
## Observability
616649

617650
You can configure Infisical to collect and expose telemetry data for analytics and monitoring.

frontend/src/hooks/api/secretScanning/mutation.ts

+10-8
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ import {
1010
} from "./types";
1111

1212
export const useCreateNewInstallationSession = () => {
13-
return useMutation<{ sessionId: string }, object, { organizationId: string }>({
14-
mutationFn: async (opt) => {
15-
const { data } = await apiRequest.post(
16-
"/api/v1/secret-scanning/create-installation-session/organization",
17-
opt
18-
);
19-
return data;
13+
return useMutation<{ sessionId: string; gitAppSlug: string }, object, { organizationId: string }>(
14+
{
15+
mutationFn: async (opt) => {
16+
const { data } = await apiRequest.post(
17+
"/api/v1/secret-scanning/create-installation-session/organization",
18+
opt
19+
);
20+
return data;
21+
}
2022
}
21-
});
23+
);
2224
};
2325

2426
export const useUpdateRiskStatus = () => {

frontend/src/pages/organization/SecretScanningPage/SecretScanningPage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ export const SecretScanningPage = withPermission(
108108

109109
const generateNewIntegrationSession = async () => {
110110
const session = await createNewIntegrationSession({ organizationId });
111-
window.location.href = `https://github.com/apps/infisical-radar/installations/new?state=${session.sessionId}`;
111+
window.location.href = `https://github.com/apps/${session.gitAppSlug}/installations/new?state=${session.sessionId}`;
112112
};
113113

114114
return (

0 commit comments

Comments
 (0)