1
0
mirror of https://github.com/Infisical/infisical.git synced 2025-04-17 19:37:38 +00:00

Compare commits

..

20 Commits

Author SHA1 Message Date
c5a422fe64 update self host docs 2022-12-05 15:26:20 -05:00
13f2ab9425 update steps number 2022-12-05 14:41:09 -05:00
ac2c50b161 Merge pull request from Infisical/upload-helm-chart-action
Upload helm chart action and docs for k8
2022-12-05 14:33:03 -05:00
afb374ff13 Add docs for k8 support 2022-12-05 14:32:16 -05:00
e98b76cba5 remove manual namespace 2022-12-05 12:57:18 -05:00
3e2ed62e50 update readme of helm repo 2022-12-05 12:31:48 -05:00
8e15dfc3d9 Merge pull request from Infisical/upload-helm-chart-action
Upload helm chart action
2022-12-05 12:20:32 -05:00
6fb22b68dd update workflow file name 2022-12-05 12:17:06 -05:00
05a19a2201 Rewrite upload steps action 2022-12-05 12:13:52 -05:00
9ee5f3d41b upload helm chart to cloudsmith 2022-12-05 12:04:23 -05:00
e67620c3ce helm release on dispatch 2022-12-05 10:48:18 -05:00
e8e6b72422 pause helm chart release 2022-12-05 10:46:56 -05:00
4cc4edcb7e Merge branch 'main' of https://github.com/Infisical/infisical into main 2022-12-05 10:45:09 -05:00
2acea4f085 push new cli release to populate release page 2022-12-05 10:45:02 -05:00
0dd546813a Create helm-chart-release.yaml 2022-12-05 10:37:33 -05:00
d82dfa5504 create helm repo install file 2022-12-05 10:28:49 -05:00
b13b0693ba Updated menu in docs 2022-12-05 00:11:47 -05:00
e00c3ab9e2 Expanded contributing docs 2022-12-05 00:07:03 -05:00
088668e1b0 Fix let -> const 2022-12-04 23:18:39 -05:00
b21cb521da Tranforming more components to typescript () 2022-12-04 23:03:57 -05:00
26 changed files with 186 additions and 63 deletions

@ -0,0 +1,22 @@
name: Release Helm Charts
on: [workflow_dispatch]
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Install Helm
uses: azure/setup-helm@v3
with:
version: v3.10.0
- name: Install python
uses: actions/setup-python@v4
- name: Install Cloudsmith CLI
run: pip install --upgrade cloudsmith-cli
- name: Build and push helm package to Cloudsmith
run: cd helm-charts && sh upload-to-cloudsmith.sh
env:
CLOUDSMITH_API_KEY: ${{ secrets.CLOUDSMITH_API_KEY }}

@ -1,4 +1,4 @@
name: goreleaser
name: Go releaser
on:
push:

@ -15,7 +15,7 @@ var rootCmd = &cobra.Command{
Short: "Infisical CLI is used to inject environment variables into any process",
Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`,
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
Version: "0.1.5",
Version: "0.1.6",
}
// Execute adds all child commands to the root command and sets flags appropriately.

16
docs/contributing/FAQ.mdx Normal file

@ -0,0 +1,16 @@
---
title: "Frequently Asked Questions"
description: "Have any questions? [Join our Slack community](https://join.slack.com/t/infisical-users/shared_invite/zt-1kdbk07ro-RtoyEt_9E~fyzGo_xQYP6g)."
---
## Problem with SMTP
You can normally populate `SMTP_USERNAME` and `SMTP_PASSWORD` with your usual login and password (you could also create a 'burner' email). Sometimes, there still are problems.
You can go to your Gmail account settings > security and enable “less secure apps”. This would allow Infisical to use your Gmail to send emails.
If it still doesn't work, [this](https://stackoverflow.com/questions/72547853/unable-to-send-email-in-c-sharp-less-secure-app-access-not-longer-available/72553362#72553362) should help.
## `MONGO_URL` issues
Your `MONGO_URL` should be something like `mongodb://root:example@mongo:27017/?authSource=admin`. If you want to change it (not recommended), you should make sure that you keep this URL in line with `MONGO_USERNAME=root` and `MONGO_PASSWORD=example`.

@ -102,8 +102,11 @@
"pages": [
"self-hosting/overview",
{
"group": "Deployments",
"pages": ["self-hosting/deployments/linux"]
"group": "Deployments options",
"pages": [
"self-hosting/deployments/linux",
"self-hosting/deployments/kubernetes"
]
},
{
"group": "Configuration",
@ -162,7 +165,8 @@
"pages": [
"contributing/overview",
"contributing/code-of-conduct",
"contributing/developing"
"contributing/developing",
"contributing/FAQ"
]
}
],

@ -0,0 +1,54 @@
---
title: "Kubernetes"
description: "Deploy with Kubernetes"
---
<Info>
Self-host vs. Infisical Cloud
Self-hosting Infisical means managing the service yourself, taking care of upgrades, scaling, security, etc.
If you're less technical and looking for a hands-free experience with minimal overhead then we recommend Infisical Cloud.
</Info>
**Prerequisites**
- You have understanding of [Kubernetes](https://kubernetes.io/)
- You have understanding of [Helm package manager](https://helm.sh/)
- You have [kubectl](https://kubernetes.io/docs/reference/kubectl/kubectl/) installed and connected to your kubernetes cluster
#### 1. Fill our environment variables
Before you can deploy the Helm chart, you must fill out the required environment variables. To do so, please either download or copy the
contents of [this file](https://raw.githubusercontent.com/Infisical/infisical/main/helm-charts/infisical/values.yaml) to a `.yaml` file.
_Refer to the available [environment variables](../../self-hosting/configuration/envars)_
Once you have a local copy of the values file, fill our the required environment variables and save the file.
#### 2. Install Infisical Helm repository
```bash
helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
helm repo update
```
#### 3. Install the Helm chart
By default, the helm chart will be installed on your default namespace. If you wish to install the Chart on a different namespace, you may specify
that by adding the `--namespace <namespace-to-install-to>` to your `helm install` command.
```bash
## Installs to default namespace
helm install infisical-helm-charts/infisical --values <path to the values.yaml you downloaded/created in step 2>
```
<Note>
If you have not filled out all of the required environment variables, you will see an error message prompting you to
do so.
</Note>
4. Your Infisical installation is complete and should be running on the host name you specified in Ingress in `values.yaml`.
Note: Please allow an additional time (2 minutes) for the frontend pods to be fully ready.

@ -9,17 +9,22 @@ Self-hosting Infisical means managing the service yourself, taking care of upgra
If you're less technical and looking for a hands-free experience with minimal overhead then we recommend Infisical Cloud.
Infisical Cloud also comes with some extra features unavailabe in the self-hosted edition. You can find more information about Infisical Cloud's offering on the pricing page.
Infisical Cloud also comes with some extra features unavailable in the self-hosted edition. You can find more information about Infisical Cloud's offering on the pricing page.
</Info>
## Deployment options
Infisical can be deployed on a Linux VM with docker-compose. We're rolling out more specific deployment options for DigitalOcean, AWS, GCP, and Azure soon.
Infisical can be deployed on a Linux VM with docker-compose and Kubernetes. We're rolling out more specific deployment options for DigitalOcean, AWS, GCP, and Azure soon.
Options:
- [Linux VM](/self-hosting/deployments/linux)
<CardGroup cols={2}>
<Card title="Any Linux" icon="square-1" color="#ea5a0c" href="/self-hosting/deployments/linux">
Deploy to any Linux with Docker
</Card>
<Card title="Kubernetes" icon="square-2" color="#0285c7" href="/self-hosting/deployments/kubernetes">
Deploy to your Kubernetes cluster
</Card>
</CardGroup>
## Telemetry

@ -37,7 +37,7 @@ const AddServiceTokenDialog = ({
const [serviceTokenCopied, setServiceTokenCopied] = useState(false);
const generateServiceToken = async () => {
const latestFileKey = await getLatestFileKey(workspaceId);
const latestFileKey = await getLatestFileKey({ workspaceId });
const key = decryptAssymmetric({
ciphertext: latestFileKey.latestKey.encryptedKey,

@ -56,10 +56,10 @@ export default function Layout({ children }) {
const workspaces = await getWorkspaces();
const currentWorkspaces = workspaces.map((workspace) => workspace.name);
if (!currentWorkspaces.includes(workspaceName)) {
const newWorkspace = await createWorkspace(
const newWorkspace = await createWorkspace({
workspaceName,
localStorage.getItem("orgData.id")
);
organizationId: localStorage.getItem("orgData.id")
});
let newWorkspaceId;
try {
newWorkspaceId = newWorkspace._id;

@ -88,7 +88,7 @@ const UserTable = ({
}, [userData, myUser]);
const grantAccess = async (id, publicKey) => {
let result = await getLatestFileKey(router.query.id);
let result = await getLatestFileKey({workspaceId: router.query.id});
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");

@ -25,12 +25,12 @@ export default function NavHeader({ pageName, isProjectRelated } : { pageName: s
useEffect(() => {
(async () => {
const orgId = localStorage.getItem("orgData.id")
let org = await getOrganization({
const org = await getOrganization({
orgId: orgId ? orgId : "",
});
setOrgName(org.name);
let workspace = await getProjectInfo({
const workspace = await getProjectInfo({
projectId: String(router.query.id),
});
setWorkspaceName(workspace.name);

@ -7,20 +7,30 @@ import { envMapping } from "../../../public/data/frequentConstants";
const crypto = require("crypto");
const {
decryptAssymmetric,
decryptSymmetric,
encryptSymmetric,
encryptAssymmetric,
} = require("../cryptography/crypto");
const nacl = require("tweetnacl");
nacl.util = require("tweetnacl-util");
export interface IK {
publicKey: string;
userId: string;
}
const pushKeys = async (obj, workspaceId, env) => {
let sharedKey = await getLatestFileKey(workspaceId);
/**
* This function pushes the keys to the database after decrypting them end-to-end
* @param {object} obj
* @param {object} obj.obj - object with all the key pairs
* @param {object} obj.workspaceId - the id of a project to which a user is pushing
* @param {object} obj.env - which environment a user is pushing to
*/
const pushKeys = async({ obj, workspaceId, env }: { obj: object; workspaceId: string; env: string; }) => {
const sharedKey = await getLatestFileKey({ workspaceId });
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
let randomBytes;
let randomBytes: string;
if (Object.keys(sharedKey).length > 0) {
// case: a (shared) key exists for the workspace
randomBytes = decryptAssymmetric({
@ -51,11 +61,11 @@ const pushKeys = async (obj, workspaceId, env) => {
iv: ivValue,
tag: tagValue,
} = encryptSymmetric({
plaintext: obj[key][0],
plaintext: obj[key as keyof typeof obj][0],
key: randomBytes,
});
const visibility = obj[key][1] != null ? obj[key][1] : "personal";
const visibility = obj[key as keyof typeof obj][1] != null ? obj[key as keyof typeof obj][1] : "personal";
return {
ciphertextKey,
@ -65,7 +75,7 @@ const pushKeys = async (obj, workspaceId, env) => {
ciphertextValue,
ivValue,
tagValue,
hashValue: crypto.createHash("sha256").update(obj[key][0]).digest("hex"),
hashValue: crypto.createHash("sha256").update(obj[key as keyof typeof obj][0]).digest("hex"),
type: visibility,
};
});
@ -76,7 +86,7 @@ const pushKeys = async (obj, workspaceId, env) => {
});
// assymmetrically encrypt key with each receiver public keys
const keys = publicKeys.map((k) => {
const keys = publicKeys.map((k: IK) => {
const { ciphertext, nonce } = encryptAssymmetric({
plaintext: randomBytes,
publicKey: k.publicKey,
@ -95,7 +105,7 @@ const pushKeys = async (obj, workspaceId, env) => {
workspaceId,
secrets,
keys,
environment: envMapping[env],
environment: envMapping[env as keyof typeof envMapping],
});
};

@ -6,7 +6,7 @@ import SecurityClient from "~/utilities/SecurityClient";
* @param {string} obj.orgId - organization Id
* @returns
*/
const getOrganizationUsers = ({ orgId }) => {
const getOrganizationUsers = ({ orgId }: { orgId: string; }) => {
return SecurityClient.fetchCall(
"/api/v1/organization/" + orgId + "/users",
{
@ -16,7 +16,7 @@ const getOrganizationUsers = ({ orgId }) => {
},
}
).then(async (res) => {
if (res.status == 200) {
if (res?.status == 200) {
return (await res.json()).users;
} else {
console.log("Failed to get org users");

@ -1,11 +1,12 @@
import SecurityClient from "~/utilities/SecurityClient";
/**
* This route creates a new workspace for a user.
* @param {*} workspaceName
* This route creates a new workspace for a user within a certain organization.
* @param {string} workspaceName - project Name
* @param {string} organizationId - org ID
* @returns
*/
const createWorkspace = (workspaceName, organizationId) => {
const createWorkspace = ( { workspaceName, organizationId }: { workspaceName: string; organizationId: string; }) => {
return SecurityClient.fetchCall("/api/v1/workspace", {
method: "POST",
headers: {
@ -16,7 +17,7 @@ const createWorkspace = (workspaceName, organizationId) => {
organizationId: organizationId,
}),
}).then(async (res) => {
if (res.status == 200) {
if (res?.status == 200) {
return (await res.json()).workspace;
} else {
console.log("Failed to create a project");

@ -2,10 +2,10 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* Get the latest key pairs from a certain workspace
* @param {*} workspaceId
* @param {string} workspaceId
* @returns
*/
const getLatestFileKey = (workspaceId) => {
const getLatestFileKey = ({ workspaceId } : { workspaceId: string; }) => {
return SecurityClient.fetchCall(
"/api/v1/key/" + workspaceId + "/latest",
{
@ -15,7 +15,7 @@ const getLatestFileKey = (workspaceId) => {
},
}
).then(async (res) => {
if (res.status == 200) {
if (res?.status == 200) {
return await res.json();
} else {
console.log("Failed to get the latest key pairs for a certain project");

@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get the public keys of everyone in your workspace.
* @param {*} req
* @param {*} res
* @param {string} workspaceId
* @returns
*/
const getWorkspaceKeys = (req, res) => {
const getWorkspaceKeys = ({ workspaceId }: { workspaceId: string; }) => {
return SecurityClient.fetchCall(
"/api/v1/workspace/" + req.workspaceId + "/keys",
"/api/v1/workspace/" + workspaceId + "/keys",
{
method: "GET",
headers: {
@ -16,7 +15,7 @@ const getWorkspaceKeys = (req, res) => {
},
}
).then(async (res) => {
if (res.status == 200) {
if (res?.status == 200) {
return (await res.json()).publicKeys;
} else {
console.log("Failed to get the public keys of everyone in the workspace");

@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get all the users in the workspace.
* @param {*} req
* @param {*} res
* @param {string} workspaceId - workspace ID
* @returns
*/
const getWorkspaceUsers = (req, res) => {
const getWorkspaceUsers = ({ workspaceId }: { workspaceId: string; }) => {
return SecurityClient.fetchCall(
"/api/v1/workspace/" + req.workspaceId + "/users",
"/api/v1/workspace/" + workspaceId + "/users",
{
method: "GET",
headers: {
@ -16,7 +15,7 @@ const getWorkspaceUsers = (req, res) => {
},
}
).then(async (res) => {
if (res.status == 200) {
if (res?.status == 200) {
return (await res.json()).users;
} else {
console.log("Failed to get Project Users");

@ -1,19 +1,17 @@
import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get the public keys of everyone in your workspace.
* @param {*} req
* @param {*} res
* This route lets us get the workspaces of a certain user
* @returns
*/
const getWorkspaces = (req, res) => {
const getWorkspaces = () => {
return SecurityClient.fetchCall("/api/v1/workspace", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(async (res) => {
if (res.status == 200) {
if (res?.status == 200) {
return (await res.json()).workspaces;
} else {
console.log("Failed to get projects");

@ -378,9 +378,9 @@ export default function Dashboard() {
} else if (duplicatesExist) {
console.log("Remove the duplicated entries first!");
} else {
// Once "Save changed is clicked", disable that button
// Once "Save changes is clicked", disable that button
setButtonReady(false);
pushKeys(obj, router.query.id, env);
pushKeys({obj, workspaceId: router.query.id, env});
/**
* Check which integrations are active for this project and environment

16
helm-charts/README.md Normal file

@ -0,0 +1,16 @@
### helm repository Setup
Assuming you have helm already installed, it is straight-forward to add a Cloudsmith-based chart repository:
```
helm repo add infisical-helm-charts 'https://dl.cloudsmith.io/public/infisical/helm-charts/helm/charts/'
helm repo update
```
### Installing a Helm Chart
```
helm install infisical-helm-charts/<name-of-helm-chart>
```
#### Available chart names
- infisical

@ -4,7 +4,6 @@ metadata:
name: {{ .Release.Name }}-backend-deployment
labels:
app: backend
namespace: {{ .Values.namespace }}
spec:
replicas: {{ .Values.backend.replicaCount }}
selector:
@ -35,7 +34,6 @@ apiVersion: v1
kind: Service
metadata:
name: infisical-backend-service
namespace: {{ .Values.namespace }}
spec:
selector:
app: backend

@ -4,7 +4,6 @@ metadata:
name: {{ .Release.Name }}-frontend-deployment
labels:
app: frontend
namespace: {{ .Values.namespace }}
spec:
replicas: {{ .Values.frontend.replicaCount }}
selector:
@ -26,7 +25,6 @@ apiVersion: v1
kind: Service
metadata:
name: infisical-frontend-service
namespace: {{ .Values.namespace }}
spec:
selector:
app: frontend

@ -3,7 +3,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: infisical-ingress
namespace: {{ .Values.namespace }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}

@ -2,7 +2,6 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
namespace: {{ .Values.namespace }}
labels:
app: mongodb
spec:
@ -30,7 +29,6 @@ apiVersion: v1
kind: Service
metadata:
name: mongodb-service
namespace: {{ .Values.namespace }}
spec:
selector:
app: mongodb

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: infisical

@ -0,0 +1,10 @@
## Loop through each helm chart directoy and build each into helm package
for d in */ ; do
helm package $d
done
## Upload each packaged helm chart
for i in *.tgz; do
[ -f "$i" ] || break
cloudsmith push helm --republish infisical/helm-charts $i
done