Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
pkspro committed Jan 14, 2025
2 parents f714920 + 957cab3 commit d69f89e
Show file tree
Hide file tree
Showing 12 changed files with 203 additions and 19 deletions.
15 changes: 13 additions & 2 deletions backend/src/ee/services/external-kms/external-kms-service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { KMSServiceException } from "@aws-sdk/client-kms";
import { STSServiceException } from "@aws-sdk/client-sts";
import { ForbiddenError } from "@casl/ability";
import slugify from "@sindresorhus/slugify";

import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { BadRequestError, InternalServerError, NotFoundError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { TKmsKeyDALFactory } from "@app/services/kms/kms-key-dal";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
Expand Down Expand Up @@ -71,7 +73,16 @@ export const externalKmsServiceFactory = ({
switch (provider.type) {
case KmsProviders.Aws:
{
const externalKms = await AwsKmsProviderFactory({ inputs: provider.inputs });
const externalKms = await AwsKmsProviderFactory({ inputs: provider.inputs }).catch((error) => {
if (error instanceof STSServiceException || error instanceof KMSServiceException) {
throw new InternalServerError({
message: error.message ? `AWS error: ${error.message}` : ""
});
}

throw error;
});

// if missing kms key this generate a new kms key id and returns new provider input
const newProviderInput = await externalKms.generateInputKmsKey();
sanitizedProviderInput = JSON.stringify(newProviderInput);
Expand Down
24 changes: 23 additions & 1 deletion backend/src/lib/config/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,29 @@ const envSchema = z
INF_APP_CONNECTION_GITHUB_APP_CLIENT_SECRET: zpStr(z.string().optional()),
INF_APP_CONNECTION_GITHUB_APP_PRIVATE_KEY: zpStr(z.string().optional()),
INF_APP_CONNECTION_GITHUB_APP_SLUG: zpStr(z.string().optional()),
INF_APP_CONNECTION_GITHUB_APP_ID: zpStr(z.string().optional())
INF_APP_CONNECTION_GITHUB_APP_ID: zpStr(z.string().optional()),

/* CORS ----------------------------------------------------------------------------- */

CORS_ALLOWED_ORIGINS: zpStr(
z
.string()
.optional()
.transform((val) => {
if (!val) return undefined;
return JSON.parse(val) as string[];
})
),

CORS_ALLOWED_HEADERS: zpStr(
z
.string()
.optional()
.transform((val) => {
if (!val) return undefined;
return JSON.parse(val) as string[];
})
)
})
// To ensure that basic encryption is always possible.
.refine(
Expand Down
11 changes: 10 additions & 1 deletion backend/src/server/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,16 @@ export const main = async ({ db, hsmModule, auditLogDb, smtp, logger, queue, key

await server.register<FastifyCorsOptions>(cors, {
credentials: true,
origin: appCfg.SITE_URL || true
...(appCfg.CORS_ALLOWED_ORIGINS?.length
? {
origin: [...appCfg.CORS_ALLOWED_ORIGINS, ...(appCfg.SITE_URL ? [appCfg.SITE_URL] : [])]
}
: {
origin: appCfg.SITE_URL || true
}),
...(appCfg.CORS_ALLOWED_HEADERS?.length && {
allowedHeaders: appCfg.CORS_ALLOWED_HEADERS
})
});

await server.register(addErrorsToResponseSchemas);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3714,7 +3714,8 @@ const syncSecretsCloudflarePages = async ({
}>(`${IntegrationUrls.CLOUDFLARE_PAGES_API_URL}/client/v4/accounts/${accessId}/pages/projects/${integration.app}`, {
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: "application/json"
Accept: "application/json",
"Cache-Control": "no-cache"
}
})
).data.result.deployment_configs[integration.targetEnvironment as string].env_vars;
Expand Down
22 changes: 22 additions & 0 deletions company/documentation/engineering/oncall-summery-template.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: "On call summary template"
sidebarTitle: "Summary template"
---

```plain
Date: MM/DD/YY-MM/DD/YY
Notable incidents:
- [<open/resolved>] <details of the incident including who was impacted. what you did to mitigate/patch the issue>
- Action items:
- <what can we do to prevent this from happening in the future?>
Notable support:
- [Customer company name] <details of the support inquiry>
- Action items:
- <what actions should be taken/has been taken to resolve this>
- <what can we do to prevent this from happening in the future?>
Comments:
<Any comments you have from your on call shift. Were there any pain points you experienced, etc?>
```
78 changes: 78 additions & 0 deletions company/documentation/engineering/oncall.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: "On call rotation"
sidebarTitle: "On call rotation"
description: "Learn about call rotation at Infisical"
---

Infisical is mission-critical software, which means minimizing service disruptions is a top priority.
To make sure we can react to any issues that come up, we have an on-call rotation that helps us to provide responsive, 24x7x365 support to our customers.
Being part of the on-call rotation is an opportunity to deepen the understanding of our infrastructure, deployment pipelines, and customer-facing systems.
Having this broader understanding of our system not only helps us design better software but also enhances the overall stability of our platform.

### On-Call Overview

**Rotation Details**

Each engineer will be on call once a week, from **Thursday to Thursday**, including weekends.
During this time, the on-call engineer is expected to be available at all times to respond to service disruption alerts.

While being on call, you are responsible for acting as the first line of defense for critical incidents and answering customer support inquiries.
During your working hours, you must respond to all support tickets or involve relevant team members with sufficient context.
Outside of working hours, you are expected to be available for any high-severity pager alerts and critical support inquiries by customers.

### Responsibilities While On Call

During your working hours, prioritize the following in this order:

1. **Responding to Alerts:**
- Monitor and respond promptly to all PagerDuty alerts.
- Investigate incidents, determine root causes, and mitigate issues.
- Refer to runbooks or any relevant documentation to resolve alarms quickly.
2. **Customer Support:**
- Actively monitor all support inquiries in [**Pylon**](https://app.usepylon.com/issues) and respond to incoming tickets.
- Debug and resolve customer issues. If you encounter a problem outside your expertise, collaborate with the relevant teammates to resolve it. This is an opportunity to learn and build context for future incidents.
3. **Sprint work:**
- Since the current on-call workload does not require all of your working hours, you are expected to work on the sprint items assigned to you.
If the on-call workload increases significantly, inform Maidul to make adjustments.
4. **Continuous Improvement:**
- Take note of recurring patterns, inefficiencies, and opportunities where we can automate to reduce on-call burdens in the future.

<Warning>
Outside of working hours, you are expected to be available and respond to any high-severity pager alerts and critical support inquiries by customers.
</Warning>

### Before You Get On Call

- **Set Up PagerDuty:** Ensure you have the PagerDuty mobile app installed, configured, and notifications enabled for Infisical services.
- **Access Required Tools:** Verify access to internal network, runbooks on Notion, [https://grafana.infisical.com](https://grafana.infisical.com/), access to aws accounts and any other access you may require.
- **AWS Permissions:** You will be granted sufficient AWS permissions before the start of your on-call shift in case you need to access production accounts.

### At the End of Your Shift

- Post an on-call summary in the Slack channel `#on-call-summaries` at the end of your shift using the following [template](/documentation/engineering/oncall-summery-template). Include notable findings, support inquires and incidents you encountered.
This will helps the rest of the team stay in the loop and open discussions on how to prevent similar issues in the future.
- Do a **handoff meeting/slack huddle** with the next engineer on call to summarize any outstanding work, unresolved issues, or any incidents that require follow-up. Ensure the next on-call engineer is fully briefed so they can pick up where you left off. **Include Maidul in this hand off call.**

### When to escalate an incident

If you are paged for incident that you cannot resolve after attempting to debug and mitigate the issue, you should not hesitate to escalate and page others in.
It’s better to get help sooner rather than later to minimize the impact on customers.

- **Paging relevant teammate:** If you’ve tried resolving an issue on your own and need additional help, page another engineer who might be relevant through PagerDuty.
- **Escalating to Maidul:** You can page Maidul at any time if you think it would be helpful.

### How to be successful on you rotations

- Be on top of all changes that get merged into main. This will help you be aware of any changes that might cause issues.
- When responding to support inquiries, double check your replies and make sure they are well written and typo-free. Always acknowledge inquiries quickly to make customers feel valued, and suggest a meeting or huddle if you need more clarity on their issues.
- When customers raise support inquiries, always consider what could have been done to make the inquiry self-serve. Could adding a tooltip next to the relevant feature provide clarity? Maybe the documentation could be more detailed or better organized?
- Document all of your notable support/findings/incidents/feature requests during on call so that it is easy to create your on call summary at the end of your on call shift.

### Resources

- [Pylon for support tickets](https://app.usepylon.com/issues)
- [AWS Portal](https://infisical.awsapps.com/start/)
- [View metrics on Grafana](https://grafana.infisical.com/)
- [Metabase](https://analytics.internal.infisical.com/)
- [Run books](https://www.notion.so/Runbooks-19e534883d6b4621b8c712194edbb687?pvs=21)
- [On call summary template](/documentation/engineering/oncall-summery-template)
8 changes: 7 additions & 1 deletion company/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,13 @@
"handbook/time-off",
"handbook/hiring",
"handbook/meetings",
"handbook/talking-to-customers"
"handbook/talking-to-customers",
{
"group": "Engineering",
"pages": [
"documentation/engineering/oncall"
]
}
]
}
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebarTitle: "InfisicalDynamicSecret CRD"
title: "InfisicalDynamicSecret CRD"
title: "Using the InfisicalDynamicSecret CRD"
description: "Learn how to generate dynamic secret leases in Infisical and sync them to your Kubernetes cluster."
---
## Overview
Expand All @@ -15,8 +15,10 @@ This CRD offers the following features:
- **Optionally trigger redeployments** of any workloads that consume the secret if you enable auto-reload.

### Prerequisites
- The operator is installed on to your Kubernetes cluster
- You have already configured a dynamic secret in Infisical
- A project within Infisical.
- A [machine identity](/docs/documentation/platform/identities/overview) ready for use in Infisical that has permissions to create dynamic secret leases in the project.
- You have already configured a dynamic secret in Infisical.
- The operator is installed on to your Kubernetes cluster.

## Configure Dynamic Secret CRD

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@ description: "Learn how to use the InfisicalPushSecret CRD to push and manage se
---


## Push Secrets to Infisical
## Overview

The **InfisicalPushSecret** CRD allows you to create secrets in your Kubernetes cluster and push them to Infisical.

### Example usage

This CRD offers the following features:
- **Push Secrets** from a Kubernetes secret into Infisical.
- **Manage secret lifecycle** of pushed secrets in Infisical. When the Kubernetes secret is updated, the operator will automatically update the secrets in Infisical. Optionally, when the Kubernetes secret is deleted, the operator will delete the secrets in Infisical automatically.

### Prerequisites

- A project within Infisical.
- A [machine identity](/docs/documentation/platform/identities/overview) ready for use in Infisical that has permissions to create secrets in your project.
- The operator is installed on to your Kubernetes cluster.

## Example usage

Below is a sample InfisicalPushSecret CRD that pushes secrets defined in a Kubernetes secret to Infisical.

Expand Down Expand Up @@ -89,7 +101,7 @@ After applying the soruce-secret.yaml file, you are ready to apply the Infisical
After applying the InfisicalPushSecret CRD, you should notice that the secrets you have defined in your source-secret.yaml file have been pushed to your specified destination in Infisical.


### InfisicalPushSecret CRD properties
## InfisicalPushSecret CRD properties

<Accordion title="hostAPI">
If you are fetching secrets from a self-hosted instance of Infisical set the value of `hostAPI` to
Expand Down Expand Up @@ -272,7 +284,7 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y

</Accordion>
<Accordion title="kubernetesAuth">
The Kubernetes machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within a Kubernetes environment.
The Kubernetes machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalPushSecret resource. This authentication method can only be used within a Kubernetes environment.
[Read more about Kubernetes Auth](/documentation/platform/identities/kubernetes-auth).
Valid fields:
- `identityId`: The identity ID of the machine identity you created.
Expand Down Expand Up @@ -326,7 +338,7 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y
```
</Accordion>
<Accordion title="gcpIamAuth">
The GCP IAM machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used both within and outside GCP environments.
The GCP IAM machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalPushSecret resource. This authentication method can only be used both within and outside GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).


Expand All @@ -344,7 +356,7 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y
```
</Accordion>
<Accordion title="gcpIdTokenAuth">
The GCP ID Token machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalSecret resource. This authentication method can only be used within GCP environments.
The GCP ID Token machine identity authentication method is used to authenticate with Infisical. The identity ID is stored in a field in the InfisicalPushSecret resource. This authentication method can only be used within GCP environments.
[Read more about Azure Auth](/documentation/platform/identities/gcp-auth).

Valid fields:
Expand Down Expand Up @@ -389,7 +401,7 @@ After applying the InfisicalPushSecret CRD, you should notice that the secrets y
</Accordion>


### Applying the InfisicalPushSecret CRD to your cluster
## Applying the InfisicalPushSecret CRD to your cluster

Once you have configured the `InfisicalPushSecret` CRD with the required fields, you can apply it to your cluster.
After applying, you should notice that the secrets have been pushed to Infisical.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebarTitle: "InfisicalSecret CRD"
title: "InfisicalSecret CRD"
title: "Using the InfisicalSecret CRD"
description: "Learn how to use the InfisicalSecret CRD to fetch secrets from Infisical and store them as native Kubernetes secret resource"
---

Expand Down
23 changes: 22 additions & 1 deletion docs/self-hosting/configuration/envars.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,27 @@ Used to configure platform-specific security and operational settings
this to `false`.
</ParamField>

## CORS

Cross-Origin Resource Sharing (CORS) is a security feature that allows web applications running on one domain to access resources from another domain.
The following environment variables can be used to configure the Infisical Rest API to allow or restrict access to resources from different origins.

<ParamField query="CORS_ALLOWED_ORIGINS" type="string" optional>

Specify a list of origins that are allowed to access the Infisical API.

An example value would be `CORS_ALLOWED_ORIGINS=["https://example.com"]`.

Defaults to the same value as your `SITE_URL` environment variable.
</ParamField>

<ParamField query="CORS_ALLOWED_METHODS" type="string" optional>
Array of HTTP methods allowed for CORS requests.

Defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header.
</ParamField>


## Data Layer

The platform utilizes Postgres to persist all of its data and Redis for caching and backgroud tasks
Expand Down Expand Up @@ -72,7 +93,7 @@ DB_READ_REPLICAS=[{"DB_CONNECTION_URI":""}]
</Expandable>
</ParamField>

## Email service
## Email Service

Without email configuration, Infisical's core functions like sign-up/login and secret operations work, but this disables multi-factor authentication, email invites for projects, alerts for suspicious logins, and all other email-dependent features.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export const UserDetailsSection = ({ membershipId, handlePopUpOpen }: Props) =>
variant="plain"
className="group relative ml-2"
onClick={() => {
navigator.clipboard.writeText("");
navigator.clipboard.writeText(membership.user.username);
setCopyTextUsername("Copied");
}}
>
Expand Down

0 comments on commit d69f89e

Please sign in to comment.