mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-24 00:15:26 +00:00
Compare commits
36 Commits
update-blo
...
infisical/
Author | SHA1 | Date | |
---|---|---|---|
356e981401 | |||
5b41fb0ff5 | |||
8893aec213 | |||
c4cb8f8008 | |||
046557c97f | |||
a15ba28c18 | |||
8386f4dcbd | |||
ada0fd9c5b | |||
6376c29e49 | |||
402692614e | |||
34de6d4e29 | |||
829e906650 | |||
b7cbb0f1a8 | |||
a50ffbb59d | |||
48eda0c684 | |||
ed89413689 | |||
0c94f77a6d | |||
e6068826f8 | |||
cfa0a2044e | |||
134b503c28 | |||
efcbf1aa88 | |||
284c18db07 | |||
1410a44610 | |||
746ffb3840 | |||
f9f12eafdf | |||
11470a5a0e | |||
9fe2190115 | |||
9e2bd31833 | |||
e88b0ad3c4 | |||
74644fd8bb | |||
2069ac1554 | |||
5a2516e0a7 | |||
b52bc3bed7 | |||
4a153e5658 | |||
7324822be5 | |||
766f301aea |
@ -6,6 +6,9 @@ export const client = new InfisicalClient({
|
||||
token: process.env.INFISICAL_TOKEN!
|
||||
});
|
||||
|
||||
export const getIsMigrationMode = async () =>
|
||||
(await client.getSecret("MIGRATION_MODE")).secretValue === "true";
|
||||
|
||||
export const getPort = async () => (await client.getSecret("PORT")).secretValue || 4000;
|
||||
export const getEncryptionKey = async () => {
|
||||
const secretValue = (await client.getSecret("ENCRYPTION_KEY")).secretValue;
|
||||
|
@ -3,11 +3,11 @@ import { IServerConfig, ServerConfig } from "../models/serverConfig";
|
||||
let serverConfig: IServerConfig;
|
||||
|
||||
export const serverConfigInit = async () => {
|
||||
const cfg = await ServerConfig.findOne({});
|
||||
const cfg = await ServerConfig.findOne({}).lean();
|
||||
if (!cfg) {
|
||||
const cfg = new ServerConfig();
|
||||
await cfg.save();
|
||||
serverConfig = cfg;
|
||||
serverConfig = cfg.toObject();
|
||||
} else {
|
||||
serverConfig = cfg;
|
||||
}
|
||||
@ -19,6 +19,6 @@ export const getServerConfig = () => serverConfig;
|
||||
export const updateServerConfig = async (data: Partial<IServerConfig>) => {
|
||||
const cfg = await ServerConfig.findByIdAndUpdate(serverConfig._id, data, { new: true });
|
||||
if (!cfg) throw new Error("Failed to update server config");
|
||||
serverConfig = cfg;
|
||||
serverConfig = cfg.toObject();
|
||||
return serverConfig;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Request, Response } from "express";
|
||||
import { getHttpsEnabled } from "../../config";
|
||||
import { getHttpsEnabled, getIsMigrationMode } from "../../config";
|
||||
import { getServerConfig, updateServerConfig as setServerConfig } from "../../config/serverConfig";
|
||||
import { initializeDefaultOrg, issueAuthTokens } from "../../helpers";
|
||||
import { validateRequest } from "../../helpers/validation";
|
||||
@ -8,9 +8,10 @@ import { TelemetryService } from "../../services";
|
||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import * as reqValidator from "../../validation/admin";
|
||||
|
||||
export const getServerConfigInfo = (_req: Request, res: Response) => {
|
||||
export const getServerConfigInfo = async (_req: Request, res: Response) => {
|
||||
const config = getServerConfig();
|
||||
return res.send({ config });
|
||||
const isMigrationModeOn = await getIsMigrationMode();
|
||||
return res.send({ config: { ...config, isMigrationModeOn } });
|
||||
};
|
||||
|
||||
export const updateServerConfig = async (req: Request, res: Response) => {
|
||||
|
@ -579,7 +579,9 @@ export const getSecretsHelper = async ({
|
||||
event: "secrets pulled",
|
||||
distinctId: await TelemetryService.getDistinctId({ authData }),
|
||||
properties: {
|
||||
numberOfSecrets: shouldRecordK8Event ? approximateForNoneCapturedEvents : secrets.length,
|
||||
numberOfSecrets: shouldRecordK8Event
|
||||
? approximateForNoneCapturedEvents
|
||||
: secrets.length,
|
||||
environment,
|
||||
workspaceId,
|
||||
folderId,
|
||||
@ -614,7 +616,6 @@ export const getSecretHelper = async ({
|
||||
include_imports = true,
|
||||
version
|
||||
}: GetSecretParams) => {
|
||||
|
||||
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
||||
secretName,
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
@ -644,7 +645,7 @@ export const getSecretHelper = async ({
|
||||
type: type ?? SECRET_PERSONAL,
|
||||
version
|
||||
}).lean();
|
||||
|
||||
|
||||
if (secretVersion) {
|
||||
secret = await new Secret({
|
||||
...secretVersion,
|
||||
@ -673,7 +674,7 @@ export const getSecretHelper = async ({
|
||||
type: SECRET_SHARED,
|
||||
version
|
||||
}).lean();
|
||||
|
||||
|
||||
if (secretVersion) {
|
||||
secret = await new Secret({
|
||||
...secretVersion,
|
||||
@ -682,10 +683,16 @@ export const getSecretHelper = async ({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!secret && include_imports) {
|
||||
// if still no secret found search in imported secret and retreive
|
||||
secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId, version);
|
||||
secret = await getAnImportedSecret(
|
||||
secretName,
|
||||
workspaceId.toString(),
|
||||
environment,
|
||||
folderId,
|
||||
version
|
||||
);
|
||||
}
|
||||
|
||||
if (!secret) throw SecretNotFoundError();
|
||||
@ -1180,11 +1187,12 @@ const recursivelyExpandSecret = async (
|
||||
const secRefKey = entities[entities.length - 1];
|
||||
|
||||
const val = await fetchCrossEnv(secRefEnv, secRefPath, secRefKey);
|
||||
interpolatedValue = interpolatedValue.replaceAll(interpolationSyntax, val);
|
||||
if (val !== undefined) {
|
||||
interpolatedValue = interpolatedValue.replaceAll(interpolationSyntax, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandedSec[key] = interpolatedValue;
|
||||
return interpolatedValue;
|
||||
};
|
||||
|
@ -83,6 +83,7 @@ import { healthCheck } from "./routes/status";
|
||||
import { RouteNotFoundError } from "./utils/errors";
|
||||
import { requestErrorHandler } from "./middleware/requestErrorHandler";
|
||||
import {
|
||||
getIsMigrationMode,
|
||||
getMongoURL,
|
||||
getNodeEnv,
|
||||
getPort,
|
||||
@ -107,8 +108,8 @@ const main = async () => {
|
||||
|
||||
const port = await getPort();
|
||||
|
||||
// initializing the database connection + redis
|
||||
await initRedis()
|
||||
// initializing the database connection + redis
|
||||
await initRedis();
|
||||
await DatabaseService.initDatabase(await getMongoURL());
|
||||
const serverCfg = await serverConfigInit();
|
||||
await setup();
|
||||
@ -198,6 +199,18 @@ const main = async () => {
|
||||
handler = nextApp.getRequestHandler();
|
||||
}
|
||||
|
||||
app.use((req, _res, next) => {
|
||||
getIsMigrationMode()
|
||||
.then((el) => {
|
||||
if (el && req.method !== "GET") {
|
||||
next(new Error("Migration mode"));
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
// (EE) routes
|
||||
app.use("/api/v1/identities", v1IdentitiesRouter);
|
||||
app.use("/api/v1/secret", eeSecretRouter);
|
||||
|
@ -76,10 +76,10 @@ export const initializeSamlStrategy = async () => {
|
||||
|
||||
if (!organization) return done(OrganizationNotFoundError());
|
||||
|
||||
const email = profile.email;
|
||||
const email = profile?.email ?? profile?.emailAddress // emailRippling is added because in Rippling the field `email` reserved
|
||||
const firstName = profile.firstName;
|
||||
const lastName = profile.lastName;
|
||||
|
||||
|
||||
let user = await User.findOne({
|
||||
email
|
||||
}).select("+publicKey");
|
||||
|
@ -498,7 +498,7 @@ var agentCmd = &cobra.Command{
|
||||
|
||||
agentConfigInBase64 := os.Getenv("INFISICAL_AGENT_CONFIG_BASE64")
|
||||
|
||||
if configPath != "" {
|
||||
if agentConfigInBase64 == "" {
|
||||
data, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
if !FileExists(configPath) {
|
||||
@ -506,7 +506,6 @@ var agentCmd = &cobra.Command{
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
agentConfigInBytes = data
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ var exportCmd = &cobra.Command{
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, WorkspaceId: projectId, SecretsPath: secretsPath})
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, WorkspaceId: projectId, SecretsPath: secretsPath}, "")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to fetch secrets")
|
||||
}
|
||||
@ -87,7 +87,7 @@ var exportCmd = &cobra.Command{
|
||||
|
||||
var output string
|
||||
if shouldExpandSecrets {
|
||||
substitutions := util.ExpandSecrets(secrets, infisicalToken)
|
||||
substitutions := util.ExpandSecrets(secrets, infisicalToken, "")
|
||||
output, err = formatEnvs(substitutions, format)
|
||||
if err != nil {
|
||||
util.HandleError(err)
|
||||
|
@ -67,6 +67,11 @@ var runCmd = &cobra.Command{
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
projectConfigDir, err := cmd.Flags().GetString("project-config-dir")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
secretOverriding, err := cmd.Flags().GetBool("secret-overriding")
|
||||
if err != nil {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
@ -92,7 +97,7 @@ var runCmd = &cobra.Command{
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath, IncludeImport: includeImports})
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath, IncludeImport: includeImports}, projectConfigDir)
|
||||
|
||||
if err != nil {
|
||||
util.HandleError(err, "Could not fetch secrets", "If you are using a service token to fetch secrets, please ensure it is valid")
|
||||
@ -105,7 +110,7 @@ var runCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if shouldExpandSecrets {
|
||||
secrets = util.ExpandSecrets(secrets, infisicalToken)
|
||||
secrets = util.ExpandSecrets(secrets, infisicalToken, projectConfigDir)
|
||||
}
|
||||
|
||||
secretsByKey := getSecretsByKeys(secrets)
|
||||
@ -198,6 +203,7 @@ func init() {
|
||||
runCmd.Flags().StringP("command", "c", "", "chained commands to execute (e.g. \"npm install && npm run dev; echo ...\")")
|
||||
runCmd.Flags().StringP("tags", "t", "", "filter secrets by tag slugs ")
|
||||
runCmd.Flags().String("path", "/", "get secrets within a folder path")
|
||||
runCmd.Flags().String("project-config-dir", "", "explicitly set the directory where the .infisical.json resides")
|
||||
}
|
||||
|
||||
// Will execute a single command and pass in the given secrets into the process
|
||||
|
@ -68,7 +68,7 @@ var secretsCmd = &cobra.Command{
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath, IncludeImport: includeImports})
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath, IncludeImport: includeImports}, "")
|
||||
if err != nil {
|
||||
util.HandleError(err)
|
||||
}
|
||||
@ -80,7 +80,7 @@ var secretsCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if shouldExpandSecrets {
|
||||
secrets = util.ExpandSecrets(secrets, infisicalToken)
|
||||
secrets = util.ExpandSecrets(secrets, infisicalToken, "")
|
||||
}
|
||||
|
||||
visualize.PrintAllSecretDetails(secrets)
|
||||
@ -169,7 +169,7 @@ var secretsSetCmd = &cobra.Command{
|
||||
plainTextEncryptionKey := crypto.DecryptAsymmetric(encryptedWorkspaceKey, encryptedWorkspaceKeyNonce, encryptedWorkspaceKeySenderPublicKey, currentUsersPrivateKey)
|
||||
|
||||
// pull current secrets
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, SecretsPath: secretsPath})
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, SecretsPath: secretsPath}, "")
|
||||
if err != nil {
|
||||
util.HandleError(err, "unable to retrieve secrets")
|
||||
}
|
||||
@ -406,7 +406,7 @@ func getSecretsByNames(cmd *cobra.Command, args []string) {
|
||||
util.HandleError(err, "Unable to parse path flag")
|
||||
}
|
||||
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath})
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath}, "")
|
||||
if err != nil {
|
||||
util.HandleError(err, "To fetch all secrets")
|
||||
}
|
||||
@ -455,7 +455,7 @@ func generateExampleEnv(cmd *cobra.Command, args []string) {
|
||||
util.HandleError(err, "Unable to parse flag")
|
||||
}
|
||||
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath})
|
||||
secrets, err := util.GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: environmentName, InfisicalToken: infisicalToken, TagSlugs: tagSlugs, SecretsPath: secretsPath}, "")
|
||||
if err != nil {
|
||||
util.HandleError(err, "To fetch all secrets")
|
||||
}
|
||||
|
@ -113,6 +113,28 @@ func GetWorkSpaceFromFile() (models.WorkspaceConfigFile, error) {
|
||||
return workspaceConfigFile, nil
|
||||
}
|
||||
|
||||
func GetWorkSpaceFromFilePath(configFileDir string) (models.WorkspaceConfigFile, error) {
|
||||
configFilePath := filepath.Join(configFileDir, ".infisical.json")
|
||||
|
||||
_, configFileStatusError := os.Stat(configFilePath)
|
||||
if os.IsNotExist(configFileStatusError) {
|
||||
return models.WorkspaceConfigFile{}, fmt.Errorf("file %s does not exist", configFilePath)
|
||||
}
|
||||
|
||||
configFileAsBytes, err := os.ReadFile(configFilePath)
|
||||
if err != nil {
|
||||
return models.WorkspaceConfigFile{}, err
|
||||
}
|
||||
|
||||
var workspaceConfigFile models.WorkspaceConfigFile
|
||||
err = json.Unmarshal(configFileAsBytes, &workspaceConfigFile)
|
||||
if err != nil {
|
||||
return models.WorkspaceConfigFile{}, err
|
||||
}
|
||||
|
||||
return workspaceConfigFile, nil
|
||||
}
|
||||
|
||||
// FindWorkspaceConfigFile searches for a .infisical.json file in the current directory and all parent directories.
|
||||
func FindWorkspaceConfigFile() (string, error) {
|
||||
dir, err := os.Getwd()
|
||||
|
@ -105,6 +105,17 @@ func RequireLocalWorkspaceFile() {
|
||||
}
|
||||
}
|
||||
|
||||
func ValidateWorkspaceFile(projectConfigFilePath string) {
|
||||
workspaceFilePath, err := GetWorkSpaceFromFilePath(projectConfigFilePath)
|
||||
if err != nil {
|
||||
PrintErrorMessageAndExit(fmt.Sprintf("error reading your project config %v", err))
|
||||
}
|
||||
|
||||
if workspaceFilePath.WorkspaceId == "" {
|
||||
PrintErrorMessageAndExit("Your project id is missing in your local config file. Please add it or run again [infisical init]")
|
||||
}
|
||||
}
|
||||
|
||||
func GetHashFromStringList(list []string) string {
|
||||
hash := sha256.New()
|
||||
|
||||
|
@ -220,7 +220,7 @@ func InjectImportedSecret(plainTextWorkspaceKey []byte, secrets []models.SingleE
|
||||
return secrets, nil
|
||||
}
|
||||
|
||||
func GetAllEnvironmentVariables(params models.GetAllSecretsParameters) ([]models.SingleEnvironmentVariable, error) {
|
||||
func GetAllEnvironmentVariables(params models.GetAllSecretsParameters, projectConfigFilePath string) ([]models.SingleEnvironmentVariable, error) {
|
||||
var infisicalToken string
|
||||
if params.InfisicalToken == "" {
|
||||
infisicalToken = os.Getenv(INFISICAL_TOKEN_NAME)
|
||||
@ -236,7 +236,13 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters) ([]models
|
||||
if infisicalToken == "" {
|
||||
if isConnected {
|
||||
log.Debug().Msg("GetAllEnvironmentVariables: Connected to internet, checking logged in creds")
|
||||
RequireLocalWorkspaceFile()
|
||||
|
||||
if projectConfigFilePath == "" {
|
||||
RequireLocalWorkspaceFile()
|
||||
} else {
|
||||
ValidateWorkspaceFile(projectConfigFilePath)
|
||||
}
|
||||
|
||||
RequireLogin()
|
||||
}
|
||||
|
||||
@ -251,13 +257,26 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters) ([]models
|
||||
PrintErrorMessageAndExit("Your login session has expired, please run [infisical login] and try again")
|
||||
}
|
||||
|
||||
workspaceFile, err := GetWorkSpaceFromFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var infisicalDotJson models.WorkspaceConfigFile
|
||||
|
||||
if projectConfigFilePath == "" {
|
||||
projectConfig, err := GetWorkSpaceFromFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infisicalDotJson = projectConfig
|
||||
} else {
|
||||
projectConfig, err := GetWorkSpaceFromFilePath(projectConfigFilePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infisicalDotJson = projectConfig
|
||||
}
|
||||
|
||||
if params.WorkspaceId != "" {
|
||||
workspaceFile.WorkspaceId = params.WorkspaceId
|
||||
infisicalDotJson.WorkspaceId = params.WorkspaceId
|
||||
}
|
||||
|
||||
// // Verify environment
|
||||
@ -266,18 +285,18 @@ func GetAllEnvironmentVariables(params models.GetAllSecretsParameters) ([]models
|
||||
// return nil, fmt.Errorf("unable to validate environment name because [err=%s]", err)
|
||||
// }
|
||||
|
||||
secretsToReturn, errorToReturn = GetPlainTextSecretsViaJTW(loggedInUserDetails.UserCredentials.JTWToken, loggedInUserDetails.UserCredentials.PrivateKey, workspaceFile.WorkspaceId,
|
||||
secretsToReturn, errorToReturn = GetPlainTextSecretsViaJTW(loggedInUserDetails.UserCredentials.JTWToken, loggedInUserDetails.UserCredentials.PrivateKey, infisicalDotJson.WorkspaceId,
|
||||
params.Environment, params.TagSlugs, params.SecretsPath, params.IncludeImport)
|
||||
log.Debug().Msgf("GetAllEnvironmentVariables: Trying to fetch secrets JTW token [err=%s]", errorToReturn)
|
||||
|
||||
backupSecretsEncryptionKey := []byte(loggedInUserDetails.UserCredentials.PrivateKey)[0:32]
|
||||
if errorToReturn == nil {
|
||||
WriteBackupSecrets(workspaceFile.WorkspaceId, params.Environment, backupSecretsEncryptionKey, secretsToReturn)
|
||||
WriteBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey, secretsToReturn)
|
||||
}
|
||||
|
||||
// only attempt to serve cached secrets if no internet connection and if at least one secret cached
|
||||
if !isConnected {
|
||||
backedSecrets, err := ReadBackupSecrets(workspaceFile.WorkspaceId, params.Environment, backupSecretsEncryptionKey)
|
||||
backedSecrets, err := ReadBackupSecrets(infisicalDotJson.WorkspaceId, params.Environment, backupSecretsEncryptionKey)
|
||||
if len(backedSecrets) > 0 {
|
||||
PrintWarning("Unable to fetch latest secret(s) due to connection error, serving secrets from last successful fetch. For more info, run with --debug")
|
||||
secretsToReturn = backedSecrets
|
||||
@ -421,7 +440,7 @@ func getSecretsByKeys(secrets []models.SingleEnvironmentVariable) map[string]mod
|
||||
return secretMapByName
|
||||
}
|
||||
|
||||
func ExpandSecrets(secrets []models.SingleEnvironmentVariable, infisicalToken string) []models.SingleEnvironmentVariable {
|
||||
func ExpandSecrets(secrets []models.SingleEnvironmentVariable, infisicalToken string, projectConfigPathDir string) []models.SingleEnvironmentVariable {
|
||||
expandedSecs := make(map[string]string)
|
||||
interpolatedSecs := make(map[string]string)
|
||||
// map[env.secret-path][keyname]Secret
|
||||
@ -454,7 +473,7 @@ func ExpandSecrets(secrets []models.SingleEnvironmentVariable, infisicalToken st
|
||||
|
||||
if crossRefSec, ok := crossEnvRefSecs[uniqKey]; !ok {
|
||||
// if not in cross reference cache, fetch it from server
|
||||
refSecs, err := GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: env, InfisicalToken: infisicalToken, SecretsPath: secPath})
|
||||
refSecs, err := GetAllEnvironmentVariables(models.GetAllSecretsParameters{Environment: env, InfisicalToken: infisicalToken, SecretsPath: secPath}, projectConfigPathDir)
|
||||
if err != nil {
|
||||
HandleError(err, fmt.Sprintf("Could not fetch secrets in environment: %s secret-path: %s", env, secPath), "If you are using a service token to fetch secrets, please ensure it is valid")
|
||||
}
|
||||
|
@ -4,6 +4,14 @@ title: "Changelog"
|
||||
|
||||
The changelog below reflects new product developments and updates on a monthly basis.
|
||||
|
||||
## January 2024
|
||||
- Reduced size of Infisical Node.js SDK by ≈90%.
|
||||
- Added secret fallback support to all SDK's.
|
||||
- Added Machine Identity support to [Terraform Provider](https://github.com/Infisical/terraform-provider-infisical).
|
||||
- Released [.NET SDK](https://infisical.com/docs/sdks/languages/csharp).
|
||||
- Added symmetric encryption support to all SDK's.
|
||||
- Fixed secret reminders bug, where reminders were not being updated correctly.
|
||||
|
||||
## December 2023
|
||||
|
||||
- Released [(machine) identities](https://infisical.com/docs/documentation/platform/identities/overview) and [universal auth](https://infisical.com/docs/documentation/platform/identities/universal-auth) features.
|
||||
|
@ -62,6 +62,16 @@ Inject secrets from Infisical into your application process.
|
||||
</Accordion>
|
||||
|
||||
### Flags
|
||||
|
||||
<Accordion title="--project-config-dir">
|
||||
Explicitly set the directory where the .infisical.json resides. This is useful for some monorepo setups.
|
||||
|
||||
```bash
|
||||
# Example
|
||||
infisical run --project-config-dir=/some-dir -- printenv
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="--command">
|
||||
Pass secrets into multiple commands at once
|
||||
|
||||
|
@ -16,5 +16,6 @@ Follow the instructions for your language use the SDK for it:
|
||||
- [Node SDK](https://infisical.com/docs/sdks/languages/node)
|
||||
- [Python SDK](https://infisical.com/docs/sdks/languages/python)
|
||||
- [Java SDK](https://infisical.com/docs/sdks/languages/java)
|
||||
- [.NET SDK](https://infisical.com/docs/sdks/languages/csharp)
|
||||
|
||||
Missing a language? [Throw in a request](https://github.com/Infisical/infisical/issues).
|
@ -5,7 +5,7 @@ title: "Node"
|
||||
This guide demonstrates how to use Infisical to manage secrets for your Node stack from local development to production. It uses:
|
||||
|
||||
- Infisical (you can use [Infisical Cloud](https://app.infisical.com) or a [self-hosted instance of Infisical](https://infisical.com/docs/self-hosting/overview)) to store your secrets.
|
||||
- The [infisical-node](https://github.com/Infisical/infisical-node) client SDK to fetch secrets back to your Node application on demand.
|
||||
- The [@infisical/sdk](https://github.com/Infisical/sdk/tree/main/languages/node) Node.js client SDK to fetch secrets back to your Node application on demand.
|
||||
|
||||
## Project Setup
|
||||
|
||||
@ -17,13 +17,11 @@ To begin, we need to set up a project in Infisical and add secrets to an environ
|
||||
|
||||
2. Add a secret to the development environment of this project so we can pull it back for local development. In the **Secrets Overview** page, press **Explore Development** and add a secret with the key `NAME` and value `YOUR_NAME`.
|
||||
|
||||
### Create an Infisical Token
|
||||
### Create a Machine Identity
|
||||
|
||||
Now that we've created a project and added a secret to its development environment, we need to provision an Infisical Token that our Node application can use to access the secret.
|
||||
Now that we've created a project and added a secret to its development environment, we need to configure an Infisical Machine Identity that our Node application can use to access the secret.
|
||||
|
||||
1. Head to the **Project Settings > Service Tokens** and press **Add New Token**.
|
||||
2. Call the token anything like **My App Token** and select **Development** under **Environment**.
|
||||
3. Copy the token and keep it handy.
|
||||
- [How to setup machine identities](/documentation/platform/identities/overview)
|
||||
|
||||
|
||||
## Create a Node app
|
||||
@ -41,27 +39,43 @@ npm init -y
|
||||
Install `express` and [infisical-node](https://github.com/Infisical/infisical-node), the client Node SDK for Infisical.
|
||||
|
||||
```console
|
||||
npm install express infisical-node
|
||||
npm install express @infisical/sdk
|
||||
```
|
||||
|
||||
Finally, create an index.js file containing the application code.
|
||||
|
||||
```js
|
||||
const express = require("express");
|
||||
const express = require('express');
|
||||
const { InfisicalClient, LogLevel } = require("@infisical/sdk");
|
||||
|
||||
const app = express();
|
||||
|
||||
const PORT = 3000;
|
||||
|
||||
const client = new InfisicalClient({
|
||||
token: "YOUR_INFISICAL_TOKEN"
|
||||
clientId: "YOUR_CLIENT_ID",
|
||||
clientSecret: "YOUR_CLIENT_SECRET",
|
||||
logLevel: LogLevel.Error
|
||||
});
|
||||
|
||||
app.get("/", async (req, res) => {
|
||||
const name = (await client.getSecret("NAME")).secretValue;
|
||||
res.send(`Hello, ${name}!`);
|
||||
// access value
|
||||
|
||||
const name = await client.getSecret({
|
||||
environment: "dev",
|
||||
projectId: "PROJECT_ID",
|
||||
path: "/",
|
||||
type: "shared",
|
||||
secretName: "NAME"
|
||||
});
|
||||
|
||||
res.send(`Hello! My name is: ${name.secretValue}`);
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Example app listening on port ${PORT}`);
|
||||
app.listen(PORT, async () => {
|
||||
// initialize client
|
||||
|
||||
console.log(`App listening on port ${port}`);
|
||||
});
|
||||
```
|
||||
|
||||
@ -82,13 +96,6 @@ At this stage, you know how to fetch secrets from Infisical back to your Node ap
|
||||
## FAQ
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Are my secrets exposed in transit every time the SDK fetches them?">
|
||||
No. Infisical uses end-to-end encryption which ensures that secrets are always encrypted in transit
|
||||
and decrypted on the client side. In fact, not even the server can decrypt your secrets (unless
|
||||
that permission is explicitly granted from within the platform).
|
||||
|
||||
Check out the [security guide](/security/overview).
|
||||
</Accordion>
|
||||
<Accordion title="Isn't it inefficient if my app makes a request every time it needs a secret?">
|
||||
The client SDK caches every secret and implements a 5-minute waiting period before
|
||||
re-requesting it. The waiting period can be controlled by setting the `cacheTTL` parameter at
|
||||
@ -98,10 +105,6 @@ At this stage, you know how to fetch secrets from Infisical back to your Node ap
|
||||
The SDK caches every secret and falls back to the cached value if a request fails. If no cached
|
||||
value ever-existed, the SDK falls back to whatever value is on `process.env`.
|
||||
</Accordion>
|
||||
<Accordion title="Can I still use process.env with the SDK?">
|
||||
Yes. If no `token` parameter is passed in at the time of initializing the client or nothing is found when requesting for a secret,
|
||||
then the SDK falls back to whatever value is on `process.env`.
|
||||
</Accordion>
|
||||
<Accordion title="What's the point if I still have to manage a token for the SDK?">
|
||||
The token enables the SDK to authenticate with Infisical to fetch back your secrets.
|
||||
Although the SDK requires you to pass in a token, it enables greater efficiency and security
|
||||
@ -118,4 +121,4 @@ At this stage, you know how to fetch secrets from Infisical back to your Node ap
|
||||
|
||||
See also:
|
||||
|
||||
- Explore the [Node SDK](https://github.com/Infisical/infisical-node)
|
||||
- Explore the [Node SDK](https://github.com/Infisical/sdk/tree/main/languages/node)
|
||||
|
@ -5,7 +5,7 @@ title: "Python"
|
||||
This guide demonstrates how to use Infisical to manage secrets for your Python stack from local development to production. It uses:
|
||||
|
||||
- Infisical (you can use [Infisical Cloud](https://app.infisical.com) or a [self-hosted instance of Infisical](https://infisical.com/docs/self-hosting/overview)) to store your secrets.
|
||||
- The [infisical-python](https://github.com/Infisical/infisical-python) client SDK to fetch secrets back to your Python application on demand.
|
||||
- The [infisical-python](https://github.com/Infisical/sdk/tree/main/crates/infisical-py) Python client SDK to fetch secrets back to your Python application on demand.
|
||||
|
||||
## Project Setup
|
||||
|
||||
@ -17,13 +17,11 @@ To begin, we need to set up a project in Infisical and add secrets to an environ
|
||||
|
||||
2. Add a secret to the development environment of this project so we can pull it back for local development. In the **Secrets Overview** page, press **Explore Development** and add a secret with the key `NAME` and value `YOUR_NAME`.
|
||||
|
||||
### Create an Infisical Token
|
||||
### Create a Machine Identity
|
||||
|
||||
Now that we've created a project and added a secret to its development environment, we need to provision an Infisical Token that our Node application can use to access the secret.
|
||||
Now that we've created a project and added a secret to its development environment, we need to configure an Infisical Machine Identity that our Python application can use to access the secret.
|
||||
|
||||
1. Head to the **Project Settings > Service Tokens** and press **Add New Token**.
|
||||
2. Call the token anything like **My App Token** and select **Development** under **Environment**.
|
||||
3. Copy the token and keep it handy.
|
||||
- [How to setup machine identities](/documentation/platform/identities/overview)
|
||||
|
||||
## Create a Python app
|
||||
|
||||
@ -38,27 +36,36 @@ python3 -m venv env
|
||||
source env/bin/activate
|
||||
```
|
||||
|
||||
Install Flask and [infisical-python](https://github.com/Infisical/infisical-python), the client Python SDK for Infisical.
|
||||
Install Flask and [infisical-python](https://github.com/Infisical/sdk/tree/main/crates/infisical-py), the client Python SDK for Infisical.
|
||||
|
||||
```console
|
||||
pip install Flask infisical
|
||||
pip install Flask infisical-python
|
||||
```
|
||||
|
||||
Finally, create an `app.py` file containing the application code.
|
||||
|
||||
```python
|
||||
```py
|
||||
from flask import Flask
|
||||
from infisical import InfisicalClient
|
||||
from infisical_client import ClientSettings, InfisicalClient, GetSecretOptions
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
client = InfisicalClient(token="your_infisical_token")
|
||||
client = InfisicalClient(ClientSettings(
|
||||
client_id="MACHINE_IDENTITY_CLIENT_ID",
|
||||
client_secret="MACHINE_IDENTITY_CLIENT_SECRET",
|
||||
))
|
||||
|
||||
@app.route("/")
|
||||
def hello_world():
|
||||
# access value
|
||||
name = client.get_secret("NAME")
|
||||
return f"Hello, {name.secret_value}!"
|
||||
|
||||
name = client.getSecret(options=GetSecretOptions(
|
||||
environment="dev",
|
||||
project_id="PROJECT_ID",
|
||||
secret_name="NAME"
|
||||
))
|
||||
|
||||
return f"Hello! My name is: {name.secret_value}"
|
||||
```
|
||||
|
||||
Here, we initialized a `client` instance of the Infisical Python SDK with the Infisical Token
|
||||
@ -78,13 +85,6 @@ At this stage, you know how to fetch secrets from Infisical back to your Python
|
||||
## FAQ
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Are my secrets exposed in transit every time the SDK fetches them?">
|
||||
No. Infisical uses end-to-end encryption which ensures that secrets are always encrypted in transit
|
||||
and decrypted on the client side. In fact, not even the server can decrypt your secrets (unless
|
||||
that permission is explicitly granted from within the platform).
|
||||
|
||||
Check out the [security guide](/security/overview).
|
||||
</Accordion>
|
||||
<Accordion title="Isn't it inefficient if my app makes a request every time it needs a secret?">
|
||||
The client SDK caches every secret and implements a 5-minute waiting period before
|
||||
re-requesting it. The waiting period can be controlled by setting the `cacheTTL` parameter at
|
||||
@ -94,10 +94,6 @@ At this stage, you know how to fetch secrets from Infisical back to your Python
|
||||
The SDK caches every secret and falls back to the cached value if a request fails. If no cached
|
||||
value ever-existed, the SDK falls back to whatever value is on `process.env`.
|
||||
</Accordion>
|
||||
<Accordion title="Can I still use process.env with the SDK?">
|
||||
Yes. If no `token` parameter is passed in at the time of initializing the client or nothing is found when requesting for a secret,
|
||||
then the SDK falls back to whatever value is on `process.env`.
|
||||
</Accordion>
|
||||
<Accordion title="What's the point if I still have to manage a token for the SDK?">
|
||||
The token enables the SDK to authenticate with Infisical to fetch back your secrets.
|
||||
Although the SDK requires you to pass in a token, it enables greater efficiency and security
|
||||
@ -114,6 +110,6 @@ At this stage, you know how to fetch secrets from Infisical back to your Python
|
||||
|
||||
See also:
|
||||
|
||||
- Explore the [Python SDK](https://github.com/Infisical/infisical-python)
|
||||
- Explore the [Python SDK](https://github.com/Infisical/sdk/tree/main/crates/infisical-py)
|
||||
|
||||
|
||||
|
@ -89,6 +89,10 @@ Then:
|
||||
- If user A fetches the secret D back, they get the value F.
|
||||
- If users B and C fetch the secret D back, they both get the value E.
|
||||
|
||||
<Info>
|
||||
Please keep in mind that secret reminders won't work with personal overrides.
|
||||
</Info>
|
||||
|
||||

|
||||
|
||||
### Drawer
|
||||
|
@ -7,9 +7,8 @@ description: "Log in to Infisical via SSO protocols"
|
||||
Infisical offers Google SSO and GitHub SSO for free across both Infisical Cloud and Infisical Self-hosted.
|
||||
|
||||
Infisical also offers SAML SSO authentication but as paid features that can be unlocked on Infisical Cloud's **Pro** tier
|
||||
or via enterprise license on self-hosted instances of Infisical. On this front, we currently support Okta, Azure AD, and JumpCloud and
|
||||
are expanding support for other IdPs in the coming months; stay tuned and feel free to request a IdP at this
|
||||
[issue](https://github.com/Infisical/infisical/issues/442).
|
||||
or via enterprise license on self-hosted instances of Infisical. On this front, we support industry-leading providers including
|
||||
Okta, Azure AD, and JumpCloud; with any questions, please reach out to [sales@infisical.com](mailto:sales@infisical.com).
|
||||
</Warning>
|
||||
|
||||
You can configure your organization in Infisical to have members authenticate with the platform via protocols like [SAML 2.0](https://en.wikipedia.org/wiki/SAML_2.0).
|
||||
@ -22,4 +21,4 @@ your IdP cannot and will not have access to the decryption key needed to decrypt
|
||||
- [GitLab SSO](/documentation/platform/sso/gitlab)
|
||||
- [Okta SAML](/documentation/platform/sso/okta)
|
||||
- [Azure SAML](/documentation/platform/sso/azure)
|
||||
- [JumpCloud SAML](/documentation/platform/sso/jumpcloud)
|
||||
- [JumpCloud SAML](/documentation/platform/sso/jumpcloud)
|
||||
|
394
docs/sdks/languages/csharp.mdx
Normal file
394
docs/sdks/languages/csharp.mdx
Normal file
@ -0,0 +1,394 @@
|
||||
---
|
||||
title: "Infisical .NET SDK"
|
||||
icon: "C#"
|
||||
---
|
||||
|
||||
If you're working with C#, the official [Infisical C# SDK](https://github.com/Infisical/sdk/tree/main/languages/csharp) package is the easiest way to fetch and work with secrets for your application.
|
||||
|
||||
- [Nuget Package](https://www.nuget.org/packages/Infisical.Sdk)
|
||||
- [Github Repository](https://github.com/Infisical/sdk/tree/main/languages/csharp)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```cs
|
||||
using Infisical.Sdk;
|
||||
|
||||
namespace Example
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
||||
var settings = new ClientSettings
|
||||
{
|
||||
ClientId = "CLIENT_ID",
|
||||
ClientSecret = "CLIENT_SECRET",
|
||||
// SiteUrl = "http://localhost:8080", <-- This line can be omitted if you're using Infisical Cloud.
|
||||
};
|
||||
var infisical = new InfisicalClient(settings);
|
||||
|
||||
var options = new GetSecretOptions
|
||||
{
|
||||
SecretName = "TEST",
|
||||
ProjectId = "PROJECT_ID",
|
||||
Environment = "dev",
|
||||
};
|
||||
var secret = infisical.GetSecret(options);
|
||||
|
||||
|
||||
Console.WriteLine($"The value of secret '{secret.SecretKey}', is: {secret.SecretValue}");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This example demonstrates how to use the Infisical C# SDK in a C# application. The application retrieves a secret named `TEST` from the `dev` environment of the `PROJECT_ID` project.
|
||||
|
||||
<Warning>
|
||||
We do not recommend hardcoding your [Machine Identity Tokens](/platform/identities/overview). Setting it as an environment variable would be best.
|
||||
</Warning>
|
||||
|
||||
# Installation
|
||||
|
||||
Run `npm` to add `@infisical/sdk` to your project.
|
||||
|
||||
```console
|
||||
$ dotnet add package Infisical.Sdk
|
||||
```
|
||||
# Configuration
|
||||
|
||||
Import the SDK and create a client instance with your [Machine Identity](/platform/identities/universal-auth).
|
||||
|
||||
```cs
|
||||
using Infisical.Sdk;
|
||||
|
||||
namespace Example
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
||||
var settings = new ClientSettings
|
||||
{
|
||||
ClientId = "CLIENT_ID",
|
||||
ClientSecret = "CLIENT_SECRET",
|
||||
};
|
||||
|
||||
var infisical = new InfisicalClient(settings); // <-- Your SDK instance!
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ClientSettings methods
|
||||
|
||||
<ParamField query="options" type="object">
|
||||
<Expandable title="properties">
|
||||
<ParamField query="ClientId" type="string" optional>
|
||||
Your machine identity client ID.
|
||||
</ParamField>
|
||||
<ParamField query="ClientSecret" type="string" optional>
|
||||
Your machine identity client secret.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="AccessToken" type="string" optional>
|
||||
An access token obtained from the machine identity login endpoint.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="CacheTtl" type="number" default="300" optional>
|
||||
Time-to-live (in seconds) for refreshing cached secrets.
|
||||
If manually set to 0, caching will be disabled, this is not recommended.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="SiteUrl()" type="string" default="https://app.infisical.com" optional>
|
||||
Your self-hosted absolute site URL including the protocol (e.g. `https://app.infisical.com`)
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
|
||||
</ParamField>
|
||||
|
||||
### Caching
|
||||
|
||||
To reduce the number of API requests, the SDK temporarily stores secrets it retrieves. By default, a secret remains cached for 5 minutes after it's first fetched. Each time it's fetched again, this 5-minute timer resets. You can adjust this caching duration by setting the "cacheTTL" option when creating the client.
|
||||
|
||||
## Working with Secrets
|
||||
|
||||
### client.ListSecrets(options)
|
||||
|
||||
```cs
|
||||
var options = new ListSecretsOptions
|
||||
{
|
||||
ProjectId = "PROJECT_ID",
|
||||
Environment = "dev",
|
||||
Path = "/foo/bar",
|
||||
AttachToProcessEnv = false,
|
||||
};
|
||||
|
||||
var secrets = infisical.ListSecrets(options);
|
||||
```
|
||||
|
||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object">
|
||||
<Expandable title="properties">
|
||||
<ParamField query="Environment" type="string" required>
|
||||
The slug name (dev, prod, etc) of the environment from where secrets should be fetched from.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="ProjectId" type="string">
|
||||
The project ID where the secret lives in.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="Path" type="string" optional>
|
||||
The path from where secrets should be fetched from.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="AttachToProcessEnv" type="boolean" default="false" optional>
|
||||
Whether or not to set the fetched secrets to the process environment. If true, you can access the secrets like so `System.getenv("SECRET_NAME")`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField query="IncludeImports" type="boolean" default="false" optional>
|
||||
Whether or not to include imported secrets from the current path. Read about [secret import](/documentation/platform/secret-reference)
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
|
||||
</ParamField>
|
||||
|
||||
### client.GetSecret(options)
|
||||
|
||||
```cs
|
||||
var options = new GetSecretOptions
|
||||
{
|
||||
SecretName = "AAAA",
|
||||
ProjectId = "659c781eb2d4fe3e307b77bd",
|
||||
Environment = "dev",
|
||||
};
|
||||
var secret = infisical.GetSecret(options);
|
||||
```
|
||||
|
||||
Retrieve a secret from Infisical.
|
||||
|
||||
By default, `GetSecret()` fetches and returns a shared secret.
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="SecretName" type="string" required>
|
||||
The key of the secret to retrieve.
|
||||
</ParamField>
|
||||
<ParamField query="ProjectId" type="string" required>
|
||||
The project ID where the secret lives in.
|
||||
</ParamField>
|
||||
<ParamField query="Environment" type="string" required>
|
||||
The slug name (dev, prod, etc) of the environment from where secrets should be fetched from.
|
||||
</ParamField>
|
||||
<ParamField query="Path" type="string" optional>
|
||||
The path from where secret should be fetched from.
|
||||
</ParamField>
|
||||
<ParamField query="Type" type="string" optional>
|
||||
The type of the secret. Valid options are "shared" or "personal". If not specified, the default value is "shared".
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
### client.CreateSecret(options)
|
||||
|
||||
```cs
|
||||
var options = new CreateSecretOptions {
|
||||
Environment = "dev",
|
||||
ProjectId = "PROJECT_ID",
|
||||
|
||||
SecretName = "NEW_SECRET",
|
||||
SecretValue = "NEW_SECRET_VALUE",
|
||||
SecretComment = "This is a new secret",
|
||||
};
|
||||
|
||||
var newSecret = infisical.CreateSecret(options);
|
||||
```
|
||||
|
||||
Create a new secret in Infisical.
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="SecretName" type="string" required>
|
||||
The key of the secret to create.
|
||||
</ParamField>
|
||||
<ParamField query="SecretValue" type="string" required>
|
||||
The value of the secret.
|
||||
</ParamField>
|
||||
<ParamField query="ProjectId" type="string" required>
|
||||
The project ID where the secret lives in.
|
||||
</ParamField>
|
||||
<ParamField query="Environment" type="string" required>
|
||||
The slug name (dev, prod, etc) of the environment from where secrets should be fetched from.
|
||||
</ParamField>
|
||||
<ParamField query="Path" type="string" optional>
|
||||
The path from where secret should be created.
|
||||
</ParamField>
|
||||
<ParamField query="Type" type="string" optional>
|
||||
The type of the secret. Valid options are "shared" or "personal". If not specified, the default value is "shared".
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
### client.UpdateSecret(options)
|
||||
|
||||
```cs
|
||||
var options = new UpdateSecretOptions {
|
||||
Environment = "dev",
|
||||
ProjectId = "PROJECT_ID",
|
||||
|
||||
SecretName = "SECRET_TO_UPDATE",
|
||||
SecretValue = "NEW VALUE"
|
||||
};
|
||||
|
||||
var updatedSecret = infisical.UpdateSecret(options);
|
||||
```
|
||||
|
||||
Update an existing secret in Infisical.
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="SecretName" type="string" required>
|
||||
The key of the secret to update.
|
||||
</ParamField>
|
||||
<ParamField query="SecretValue" type="string" required>
|
||||
The new value of the secret.
|
||||
</ParamField>
|
||||
<ParamField query="ProjectId" type="string" required>
|
||||
The project ID where the secret lives in.
|
||||
</ParamField>
|
||||
<ParamField query="Environment" type="string" required>
|
||||
The slug name (dev, prod, etc) of the environment from where secrets should be fetched from.
|
||||
</ParamField>
|
||||
<ParamField query="Path" type="string" optional>
|
||||
The path from where secret should be updated.
|
||||
</ParamField>
|
||||
<ParamField query="Type" type="string" optional>
|
||||
The type of the secret. Valid options are "shared" or "personal". If not specified, the default value is "shared".
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
### client.DeleteSecret(options)
|
||||
|
||||
```cs
|
||||
var options = new DeleteSecretOptions
|
||||
{
|
||||
Environment = "dev",
|
||||
ProjectId = "PROJECT_ID",
|
||||
SecretName = "NEW_SECRET",
|
||||
};
|
||||
|
||||
var deletedSecret = infisical.DeleteSecret(options);
|
||||
```
|
||||
|
||||
Delete a secret in Infisical.
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="SecretName" type="string">
|
||||
The key of the secret to update.
|
||||
</ParamField>
|
||||
<ParamField query="ProjectId" type="string" required>
|
||||
The project ID where the secret lives in.
|
||||
</ParamField>
|
||||
<ParamField query="Environment" type="string" required>
|
||||
The slug name (dev, prod, etc) of the environment from where secrets should be fetched from.
|
||||
</ParamField>
|
||||
<ParamField query="Path" type="string" optional>
|
||||
The path from where secret should be deleted.
|
||||
</ParamField>
|
||||
<ParamField query="Type" type="string" optional>
|
||||
The type of the secret. Valid options are "shared" or "personal". If not specified, the default value is "shared".
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
## Cryptography
|
||||
|
||||
### Create a symmetric key
|
||||
|
||||
Create a base64-encoded, 256-bit symmetric key to be used for encryption/decryption.
|
||||
|
||||
```cs
|
||||
var key = infisical.CreateSymmetricKey();
|
||||
```
|
||||
|
||||
#### Returns (string)
|
||||
`key` (string): A base64-encoded, 256-bit symmetric key, that can be used for encryption/decryption purposes.
|
||||
|
||||
### Encrypt symmetric
|
||||
```cs
|
||||
var options = new EncryptSymmetricOptions
|
||||
{
|
||||
Plaintext = "Infisical is awesome!",
|
||||
Key = key,
|
||||
};
|
||||
|
||||
var encryptedData = infisical.EncryptSymmetric(options);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="Plaintext" type="string">
|
||||
The plaintext you want to encrypt.
|
||||
</ParamField>
|
||||
<ParamField query="Key" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (object)
|
||||
`Tag` (string): A base64-encoded, 128-bit authentication tag.
|
||||
`Iv` (string): A base64-encoded, 96-bit initialization vector.
|
||||
`CipherText` (string): A base64-encoded, encrypted ciphertext.
|
||||
|
||||
### Decrypt symmetric
|
||||
```cs
|
||||
var decryptOptions = new DecryptSymmetricOptions
|
||||
{
|
||||
Key = key,
|
||||
Ciphertext = encryptedData.Ciphertext,
|
||||
Iv = encryptedData.Iv,
|
||||
Tag = encryptedData.Tag,
|
||||
};
|
||||
|
||||
var decryptedPlaintext = infisical.DecryptSymmetric(decryptOptions);
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="Ciphertext" type="string">
|
||||
The ciphertext you want to decrypt.
|
||||
</ParamField>
|
||||
<ParamField query="Key" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
<ParamField query="Iv" type="string" required>
|
||||
The initialization vector to use for decryption.
|
||||
</ParamField>
|
||||
<ParamField query="Tag" type="string" required>
|
||||
The authentication tag to use for decryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (string)
|
||||
`Plaintext` (string): The decrypted plaintext.
|
||||
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
title: "Go"
|
||||
icon: "golang"
|
||||
---
|
||||
|
||||
Coming soon.
|
||||
|
||||
Star our GitHub repository to stay updated [cross-language SDK](https://github.com/Infisical/sdk) GitHub repository to stay updated.
|
@ -1,10 +1,13 @@
|
||||
---
|
||||
title: "Java"
|
||||
title: "Infisical Java SDK"
|
||||
icon: "java"
|
||||
---
|
||||
|
||||
If you're working with Java, the official [Infisical Java SDK](https://github.com/Infisical/sdk/tree/main/languages/java) package is the easiest way to fetch and work with secrets for your application.
|
||||
|
||||
- [Maven Package](https://github.com/Infisical/sdk/packages/2019741)
|
||||
- [Github Repository](https://github.com/Infisical/sdk/tree/main/languages/java)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```java
|
||||
@ -121,7 +124,7 @@ SecretElement[] secrets = client.listSecrets(options);
|
||||
|
||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||
|
||||
### Methods
|
||||
#### Methods
|
||||
|
||||
<ParamField query="Parameters" type="object">
|
||||
<Expandable title="properties">
|
||||
@ -165,7 +168,7 @@ Retrieve a secret from Infisical.
|
||||
|
||||
By default, `getSecret()` fetches and returns a shared secret.
|
||||
|
||||
### Methods
|
||||
#### Methods
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -203,7 +206,7 @@ CreateSecretResponseSecret newSecret = client.createSecret(createOptions);
|
||||
|
||||
Create a new secret in Infisical.
|
||||
|
||||
### Methods
|
||||
#### Methods
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -245,7 +248,7 @@ UpdateSecretResponseSecret updatedSecret = client.updateSecret(options);
|
||||
|
||||
Update an existing secret in Infisical.
|
||||
|
||||
### Methods
|
||||
#### Methods
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -286,7 +289,7 @@ DeleteSecretResponseSecret deletedSecret = client.deleteSecret(options);
|
||||
|
||||
Delete a secret in Infisical.
|
||||
|
||||
### Methods
|
||||
#### Methods
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -307,3 +310,76 @@ Delete a secret in Infisical.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
## Cryptography
|
||||
|
||||
### Create a symmetric key
|
||||
|
||||
Create a base64-encoded, 256-bit symmetric key to be used for encryption/decryption.
|
||||
|
||||
```java
|
||||
String key = client.createSymmetricKey();
|
||||
```
|
||||
|
||||
#### Returns (string)
|
||||
`key` (string): A base64-encoded, 256-bit symmetric key, that can be used for encryption/decryption purposes.
|
||||
|
||||
### Encrypt symmetric
|
||||
```java
|
||||
EncryptSymmetricOptions options = new EncryptSymmetricOptions();
|
||||
options.setKey(key);
|
||||
options.setPlaintext("Infisical is awesome!");
|
||||
|
||||
EncryptSymmetricResponse encryptedData = client.encryptSymmetric(options);
|
||||
```
|
||||
|
||||
#### Methods
|
||||
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="setPlaintext()" type="string">
|
||||
The plaintext you want to encrypt.
|
||||
</ParamField>
|
||||
<ParamField query="setKey()" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (object)
|
||||
`tag (getTag())` (string): A base64-encoded, 128-bit authentication tag.
|
||||
`iv (getIv())` (string): A base64-encoded, 96-bit initialization vector.
|
||||
`ciphertext (getCipherText())` (string): A base64-encoded, encrypted ciphertext.
|
||||
|
||||
|
||||
### Decrypt symmetric
|
||||
```java
|
||||
DecryptSymmetricOptions decryptOptions = new DecryptSymmetricOptions();
|
||||
decryptOptions.setKey(key);
|
||||
decryptOptions.setCiphertext(encryptedData.getCiphertext());
|
||||
decryptOptions.setIv(encryptedData.getIv());
|
||||
decryptOptions.setTag(encryptedData.getTag());
|
||||
|
||||
String decryptedString = client.decryptSymmetric(decryptOptions);
|
||||
```
|
||||
|
||||
#### Methods
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="setCiphertext()" type="string">
|
||||
The ciphertext you want to decrypt.
|
||||
</ParamField>
|
||||
<ParamField query="setKey()" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
<ParamField query="setIv()" type="string" required>
|
||||
The initialization vector to use for decryption.
|
||||
</ParamField>
|
||||
<ParamField query="setTag()" type="string" required>
|
||||
The authentication tag to use for decryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (string)
|
||||
`Plaintext` (string): The decrypted plaintext.
|
@ -1,10 +1,13 @@
|
||||
---
|
||||
title: "Node"
|
||||
title: "Infisical Node.js SDK"
|
||||
icon: "node"
|
||||
---
|
||||
|
||||
If you're working with Node.js, the official [infisical-node](https://github.com/Infisical/sdk/tree/main/languages/node) package is the easiest way to fetch and work with secrets for your application.
|
||||
|
||||
- [NPM Package](https://www.npmjs.com/package/@infisical/sdk)
|
||||
- [Github Repository](https://github.com/Infisical/sdk/tree/main/languages/node)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```js
|
||||
@ -84,12 +87,12 @@ Import the SDK and create a client instance with your [Machine Identity](/docume
|
||||
clientSecret: "YOUR_CLIENT_SECRET",
|
||||
logLevel: LogLevel.Error
|
||||
});
|
||||
````
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="options" type="object">
|
||||
<Expandable title="properties">
|
||||
@ -138,7 +141,7 @@ const secrets = await client.listSecrets({
|
||||
|
||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object">
|
||||
<Expandable title="properties">
|
||||
@ -180,7 +183,7 @@ Retrieve a secret from Infisical.
|
||||
|
||||
By default, `getSecret()` fetches and returns a shared secret.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -255,7 +258,7 @@ const updatedApiKey = await client.updateSecret({
|
||||
|
||||
Update an existing secret in Infisical.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -315,3 +318,73 @@ Delete a secret in Infisical.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
## Cryptography
|
||||
|
||||
### Create a symmetric key
|
||||
|
||||
Create a base64-encoded, 256-bit symmetric key to be used for encryption/decryption.
|
||||
|
||||
```js
|
||||
const key = client.createSymmetricKey();
|
||||
```
|
||||
|
||||
#### Returns (string)
|
||||
`key` (string): A base64-encoded, 256-bit symmetric key, that can be used for encryption/decryption purposes.
|
||||
|
||||
### Encrypt symmetric
|
||||
```js
|
||||
const { iv, tag, ciphertext } = await client.encryptSymmetric({
|
||||
key: key,
|
||||
plaintext: "Infisical is awesome!",
|
||||
})
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="plaintext" type="string">
|
||||
The plaintext you want to encrypt.
|
||||
</ParamField>
|
||||
<ParamField query="key" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (object)
|
||||
`tag` (string): A base64-encoded, 128-bit authentication tag.
|
||||
`iv` (string): A base64-encoded, 96-bit initialization vector.
|
||||
`ciphertext` (string): A base64-encoded, encrypted ciphertext.
|
||||
|
||||
### Decrypt symmetric
|
||||
```js
|
||||
const decryptedString = await client.decryptSymmetric({
|
||||
key: key,
|
||||
iv: iv,
|
||||
tag: tag,
|
||||
ciphertext: ciphertext,
|
||||
});
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="ciphertext" type="string">
|
||||
The ciphertext you want to decrypt.
|
||||
</ParamField>
|
||||
<ParamField query="key" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
<ParamField query="iv" type="string" required>
|
||||
The initialization vector to use for decryption.
|
||||
</ParamField>
|
||||
<ParamField query="tag" type="string" required>
|
||||
The authentication tag to use for decryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (string)
|
||||
`plaintext` (string): The decrypted plaintext.
|
||||
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
title: "PHP"
|
||||
icon: "php"
|
||||
---
|
||||
|
||||
Coming soon.
|
||||
|
||||
Star our GitHub repository to stay updated [cross-language SDK](https://github.com/Infisical/sdk) GitHub repository to stay updated.
|
@ -1,10 +1,13 @@
|
||||
---
|
||||
title: "Python"
|
||||
title: "Infisical Python SDK"
|
||||
icon: "python"
|
||||
---
|
||||
|
||||
If you're working with Python, the official [infisical-python](https://github.com/Infisical/sdk/edit/main/crates/infisical-py) package is the easiest way to fetch and work with secrets for your application.
|
||||
|
||||
- [PyPi Package](https://pypi.org/project/infisical-python/)
|
||||
- [Github Repository](https://github.com/Infisical/sdk/edit/main/crates/infisical-py)
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```py
|
||||
@ -60,7 +63,7 @@ client = InfisicalClient(ClientSettings(
|
||||
))
|
||||
```
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="options" type="object">
|
||||
<Expandable title="properties">
|
||||
@ -110,7 +113,7 @@ client.listSecrets(options=ListSecretsOptions(
|
||||
|
||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object">
|
||||
<Expandable title="properties">
|
||||
@ -149,7 +152,7 @@ value = secret.secret_value # get its value
|
||||
|
||||
By default, `getSecret()` fetches and returns a shared secret. If not found, it returns a personal secret.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -187,7 +190,7 @@ api_key = client.createSecret(options=CreateSecretOptions(
|
||||
|
||||
Create a new secret in Infisical.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -225,7 +228,7 @@ client.updateSecret(options=UpdateSecretOptions(
|
||||
|
||||
Update an existing secret in Infisical.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -262,7 +265,7 @@ client.deleteSecret(options=DeleteSecretOptions(
|
||||
|
||||
Delete a secret in Infisical.
|
||||
|
||||
### Parameters
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" optional>
|
||||
<Expandable title="properties">
|
||||
@ -283,3 +286,79 @@ Delete a secret in Infisical.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
## Cryptography
|
||||
|
||||
### Create a symmetric key
|
||||
|
||||
Create a base64-encoded, 256-bit symmetric key to be used for encryption/decryption.
|
||||
|
||||
```py
|
||||
key = client.createSymmetricKey()
|
||||
```
|
||||
|
||||
#### Returns (string)
|
||||
`key` (string): A base64-encoded, 256-bit symmetric key, that can be used for encryption/decryption purposes.
|
||||
|
||||
### Encrypt symmetric
|
||||
```py
|
||||
encryptOptions = EncryptSymmetricOptions(
|
||||
key=key,
|
||||
plaintext="Infisical is awesome!"
|
||||
)
|
||||
|
||||
encryptedData = client.encryptSymmetric(encryptOptions)
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="plaintext" type="string">
|
||||
The plaintext you want to encrypt.
|
||||
</ParamField>
|
||||
<ParamField query="key" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (object)
|
||||
`tag` (string): A base64-encoded, 128-bit authentication tag.
|
||||
`iv` (string): A base64-encoded, 96-bit initialization vector.
|
||||
`ciphertext` (string): A base64-encoded, encrypted ciphertext.
|
||||
|
||||
### Decrypt symmetric
|
||||
```py
|
||||
decryptOptions = DecryptSymmetricOptions(
|
||||
ciphertext=encryptedData.ciphertext,
|
||||
iv=encryptedData.iv,
|
||||
tag=encryptedData.tag,
|
||||
key=key
|
||||
)
|
||||
|
||||
decryptedString = client.decryptSymmetric(decryptOptions)
|
||||
|
||||
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
<ParamField query="Parameters" type="object" required>
|
||||
<Expandable title="properties">
|
||||
<ParamField query="ciphertext" type="string">
|
||||
The ciphertext you want to decrypt.
|
||||
</ParamField>
|
||||
<ParamField query="key" type="string" required>
|
||||
The symmetric key to use for encryption.
|
||||
</ParamField>
|
||||
<ParamField query="iv" type="string" required>
|
||||
The initialization vector to use for decryption.
|
||||
</ParamField>
|
||||
<ParamField query="tag" type="string" required>
|
||||
The authentication tag to use for decryption.
|
||||
</ParamField>
|
||||
</Expandable>
|
||||
</ParamField>
|
||||
|
||||
#### Returns (string)
|
||||
`plaintext` (string): The decrypted plaintext.
|
||||
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
title: "Ruby"
|
||||
icon: "gem"
|
||||
---
|
||||
|
||||
Coming soon.
|
||||
|
||||
Star our GitHub repository to stay updated [cross-language SDK](https://github.com/Infisical/sdk) GitHub repository to stay updated.
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
title: "Rust"
|
||||
icon: "rust"
|
||||
---
|
||||
|
||||
Coming soon.
|
||||
|
||||
Star our GitHub repository to stay updated [cross-language SDK](https://github.com/Infisical/sdk) GitHub repository to stay updated.
|
@ -18,17 +18,8 @@ From local development to production, Infisical SDKs provide the easiest way for
|
||||
<Card href="/sdks/languages/java" title="Java" icon="java" color="#e41f23">
|
||||
Manage secrets for your Java application on demand
|
||||
</Card>
|
||||
<Card href="/sdks/languages/ruby" title="Ruby" icon="gem" color="#ac0d01">
|
||||
Manage secrets for your Ruby application on demand
|
||||
</Card>
|
||||
<Card href="/sdks/languages/go" title="Golang" icon="golang" color="#00add8">
|
||||
Manage secrets for your Go application on demand
|
||||
</Card>
|
||||
<Card href="/sdks/languages/rust" title="Rust" icon="rust" color="#cd412b">
|
||||
Manage secrets for your Rust application on demand
|
||||
</Card>
|
||||
<Card href="/sdks/languages/php" title="PHP" icon="php" color="#787cb4">
|
||||
Manage secrets for your PHP application on demand
|
||||
<Card href="/sdks/languages/csharp" title="C#" icon="bars" color="#368833">
|
||||
Manage secrets for your C#/.NET application on demand
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -41,6 +32,10 @@ From local development to production, Infisical SDKs provide the easiest way for
|
||||
|
||||
Note: The exact parameter name may differ depending on the language.
|
||||
</Accordion>
|
||||
<Accordion title="What if a request for a secret fails?">
|
||||
The SDK caches every secret and falls back to the cached value if a request fails. If no cached
|
||||
value ever-existed, the SDK falls back to whatever value is on the process environment.
|
||||
</Accordion>
|
||||
<Accordion title="Can I attach the environment variables to my process environment?">
|
||||
Yes you can! The client SDK provides a method to attach the secrets to your process environment. When using the `listSecrets()` method, you
|
||||
can pass a `attachToProcessEnv` parameter, which tells the SDK to attach all the found secrets to your process environment.
|
||||
|
BIN
frontend/public/images/maintenance.png
Normal file
BIN
frontend/public/images/maintenance.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 708 KiB |
@ -58,7 +58,10 @@ const Alert = forwardRef<
|
||||
{typeof icon !== "undefined" ? (
|
||||
<>{icon} </>
|
||||
) : (
|
||||
<FontAwesomeIcon className="text-lg" icon={variantIconMap[variant ?? "default"]} />
|
||||
<FontAwesomeIcon
|
||||
className="text-lg text-primary"
|
||||
icon={variantIconMap[variant ?? "default"]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-col gap-y-1">
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { createContext, ReactNode, useContext, useEffect, useMemo } from "react";
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { ContentLoader } from "@app/components/v2/ContentLoader";
|
||||
@ -27,11 +28,37 @@ export const ServerConfigProvider = ({ children }: Props): JSX.Element => {
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading && data && !data.initialized) {
|
||||
if (!isLoading && data && !data.initialized && !data.isMigrationModeOn) {
|
||||
router.push("/admin/signup");
|
||||
}
|
||||
}, [isLoading, data]);
|
||||
|
||||
if (!isLoading && data?.isMigrationModeOn) {
|
||||
return (
|
||||
<div className="relative mx-auto flex h-screen w-full flex-col items-center justify-center space-y-8 bg-bunker-800 px-8 text-mineshaft-50 dark:[color-scheme:dark]">
|
||||
<Head>
|
||||
<title>Infisical Maintenance Mode</title>
|
||||
<link rel='icon' href='/infisical.ico' />
|
||||
</Head>
|
||||
<img src="/images/maintenance.png" height={175} width={300} alt="maintenance mode" className="w-[40rem]"/>
|
||||
<p className="mx-8 mb-4 flex justify-center bg-gradient-to-tr from-mineshaft-300 to-white bg-clip-text text-4xl font-bold text-transparent md:mx-16">
|
||||
Scheduled Maintenance
|
||||
</p>
|
||||
<div className="mt-2 text-center text-lg text-bunker-300">
|
||||
Infisical is undergoing planned maintenance. <br /> No action is required on your end — your applications will continue to fetch secrets.
|
||||
<br /> If you have questions, please <a
|
||||
className="text-bunker-300 underline underline-offset-4 decoration-primary-800 hover:decoration-primary-600 hover:text-mineshaft-100 duration-200"
|
||||
href="https://infisical.com/slack"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
join our Slack community
|
||||
</a>.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isLoading || (!data?.initialized && router.pathname !== "/admin/signup")) {
|
||||
return (
|
||||
<div className="bg-bunker-800">
|
||||
|
@ -1,6 +1,7 @@
|
||||
export type TServerConfig = {
|
||||
initialized: boolean;
|
||||
allowSignUp: boolean;
|
||||
isMigrationModeOn?: boolean;
|
||||
};
|
||||
|
||||
export type TCreateAdminUserDTO = {
|
||||
|
@ -23,7 +23,9 @@ import {
|
||||
faNetworkWired,
|
||||
faPlug,
|
||||
faPlus,
|
||||
faUserPlus
|
||||
faUserPlus,
|
||||
faWarning,
|
||||
faXmark
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { yupResolver } from "@hookform/resolvers/yup";
|
||||
@ -56,6 +58,7 @@ import {
|
||||
fetchOrgUsers,
|
||||
useAddUserToWs,
|
||||
useCreateWorkspace,
|
||||
useGetUserAction,
|
||||
useRegisterUserAction,
|
||||
useUploadWsKey
|
||||
} from "@app/hooks/api";
|
||||
@ -70,13 +73,12 @@ const features = [
|
||||
link: "https://infisical.com/docs/documentation/getting-started/kubernetes",
|
||||
description:
|
||||
"Pull secrets into your Kubernetes containers and automatically redeploy upon secret changes."
|
||||
},
|
||||
},
|
||||
{
|
||||
_id: 1,
|
||||
name: "Infisical Agent",
|
||||
link: "https://infisical.com/docs/infisical-agent/overview",
|
||||
description:
|
||||
"Inject secrets into your apps without modifying any application logic."
|
||||
description: "Inject secrets into your apps without modifying any application logic."
|
||||
}
|
||||
];
|
||||
|
||||
@ -122,13 +124,13 @@ const CodeItem = ({
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<p className="mb-2 mt-4 text-bunker-300 text-sm leading-normal">{textExplanation}</p>
|
||||
<div className="font-mono text-sm px-3 py-2 bg-bunker rounded-md border border-mineshaft-600 flex flex-row items-center justify-between">
|
||||
<p className="mb-2 mt-4 text-sm leading-normal text-bunker-300">{textExplanation}</p>
|
||||
<div className="flex flex-row items-center justify-between rounded-md border border-mineshaft-600 bg-bunker px-3 py-2 font-mono text-sm">
|
||||
<input disabled value={code} id={id} className="w-full bg-transparent text-bunker-200" />
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copyToClipboard(id, setIsCopied)}
|
||||
className="h-full pl-3.5 pr-2 text-bunker-300 hover:text-primary-200 duration-200"
|
||||
className="h-full pl-3.5 pr-2 text-bunker-300 duration-200 hover:text-primary-200"
|
||||
>
|
||||
{isCopied ? (
|
||||
<FontAwesomeIcon icon={faCheck} className="pr-0.5" />
|
||||
@ -150,21 +152,21 @@ const TabsObject = () => {
|
||||
|
||||
return (
|
||||
<Tabs.Root
|
||||
className="flex flex-col w-full cursor-default border border-mineshaft-600 rounded-md"
|
||||
className="flex w-full cursor-default flex-col rounded-md border border-mineshaft-600"
|
||||
defaultValue="tab1"
|
||||
>
|
||||
<Tabs.List
|
||||
className="shrink-0 flex border-b border-mineshaft-600"
|
||||
className="flex shrink-0 border-b border-mineshaft-600"
|
||||
aria-label="Manage your account"
|
||||
>
|
||||
<Tabs.Trigger
|
||||
className="bg-bunker-700 px-5 h-10 flex-1 flex items-center justify-center text-sm leading-none text-bunker-300 select-none first:rounded-tl-md last:rounded-tr-md data-[state=active]:text-primary data-[state=active]:font-medium data-[state=active]:focus:relative data-[state=active]:border-b data-[state=active]:border-primary outline-none cursor-default"
|
||||
className="flex h-10 flex-1 cursor-default select-none items-center justify-center bg-bunker-700 px-5 text-sm leading-none text-bunker-300 outline-none first:rounded-tl-md last:rounded-tr-md data-[state=active]:border-b data-[state=active]:border-primary data-[state=active]:font-medium data-[state=active]:text-primary data-[state=active]:focus:relative"
|
||||
value="tab1"
|
||||
>
|
||||
MacOS
|
||||
</Tabs.Trigger>
|
||||
<Tabs.Trigger
|
||||
className="bg-bunker-700 px-5 h-10 flex-1 flex items-center justify-center text-sm leading-none text-bunker-300 select-none first:rounded-tl-md last:rounded-tr-md data-[state=active]:text-primary data-[state=active]:font-medium data-[state=active]:focus:relative data-[state=active]:border-b data-[state=active]:border-primary outline-none cursor-default"
|
||||
className="flex h-10 flex-1 cursor-default select-none items-center justify-center bg-bunker-700 px-5 text-sm leading-none text-bunker-300 outline-none first:rounded-tl-md last:rounded-tr-md data-[state=active]:border-b data-[state=active]:border-primary data-[state=active]:font-medium data-[state=active]:text-primary data-[state=active]:focus:relative"
|
||||
value="tab2"
|
||||
>
|
||||
Windows
|
||||
@ -178,14 +180,14 @@ const TabsObject = () => {
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="bg-bunker-700 hover:text-bunker-100 duration-200 px-5 h-10 flex-1 flex items-center justify-center text-sm leading-none text-bunker-300 select-none first:rounded-tl-md last:rounded-tr-md data-[state=active]:text-primary data-[state=active]:font-medium data-[state=active]:focus:relative data-[state=active]:border-b data-[state=active]:border-primary outline-none cursor-default"
|
||||
className="flex h-10 flex-1 cursor-default select-none items-center justify-center bg-bunker-700 px-5 text-sm leading-none text-bunker-300 outline-none duration-200 first:rounded-tl-md last:rounded-tr-md hover:text-bunker-100 data-[state=active]:border-b data-[state=active]:border-primary data-[state=active]:font-medium data-[state=active]:text-primary data-[state=active]:focus:relative"
|
||||
href="https://infisical.com/docs/cli/overview"
|
||||
>
|
||||
Other Platforms <FontAwesomeIcon icon={faArrowUpRightFromSquare} className="ml-2" />
|
||||
</a>
|
||||
</Tabs.List>
|
||||
<Tabs.Content
|
||||
className="grow p-5 pt-0 bg-bunker-700 rounded-b-md outline-none cursor-default"
|
||||
className="grow cursor-default rounded-b-md bg-bunker-700 p-5 pt-0 outline-none"
|
||||
value="tab1"
|
||||
>
|
||||
<CodeItem
|
||||
@ -216,7 +218,7 @@ const TabsObject = () => {
|
||||
code="infisical run -- [YOUR USUAL CODE START SCRIPT GOES HERE]"
|
||||
id="runCode"
|
||||
/>
|
||||
<p className="text-bunker-300 text-sm mt-2">
|
||||
<p className="mt-2 text-sm text-bunker-300">
|
||||
You can find example of start commands for different frameworks{" "}
|
||||
<a
|
||||
className="text-primary underline underline-offset-2"
|
||||
@ -229,7 +231,7 @@ const TabsObject = () => {
|
||||
.{" "}
|
||||
</p>
|
||||
</Tabs.Content>
|
||||
<Tabs.Content className="grow p-5 pt-0 bg-bunker-700 rounded-b-md outline-none" value="tab2">
|
||||
<Tabs.Content className="grow rounded-b-md bg-bunker-700 p-5 pt-0 outline-none" value="tab2">
|
||||
<CodeItem
|
||||
isCopied={downloadCodeCopied}
|
||||
setIsCopied={setDownloadCodeCopied}
|
||||
@ -237,7 +239,7 @@ const TabsObject = () => {
|
||||
code="scoop bucket add org https://github.com/Infisical/scoop-infisical.git"
|
||||
id="downloadCodeW"
|
||||
/>
|
||||
<div className="font-mono text-sm px-3 py-2 mt-2 bg-bunker rounded-md border border-mineshaft-600 flex flex-row items-center justify-between">
|
||||
<div className="mt-2 flex flex-row items-center justify-between rounded-md border border-mineshaft-600 bg-bunker px-3 py-2 font-mono text-sm">
|
||||
<input
|
||||
disabled
|
||||
value="scoop install infisical"
|
||||
@ -247,7 +249,7 @@ const TabsObject = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copyToClipboard("downloadCodeW2", setDownloadCode2Copied)}
|
||||
className="h-full pl-3.5 pr-2 text-bunker-300 hover:text-primary-200 duration-200"
|
||||
className="h-full pl-3.5 pr-2 text-bunker-300 duration-200 hover:text-primary-200"
|
||||
>
|
||||
{downloadCode2Copied ? (
|
||||
<FontAwesomeIcon icon={faCheck} className="pr-0.5" />
|
||||
@ -277,7 +279,7 @@ const TabsObject = () => {
|
||||
code="infisical run -- [YOUR USUAL CODE START SCRIPT GOES HERE]"
|
||||
id="runCodeW"
|
||||
/>
|
||||
<p className="text-bunker-300 text-sm mt-2">
|
||||
<p className="mt-2 text-sm text-bunker-300">
|
||||
You can find example of start commands for different frameworks{" "}
|
||||
<a
|
||||
className="text-primary underline underline-offset-2"
|
||||
@ -481,6 +483,13 @@ const OrganizationPage = withPermission(
|
||||
const { createNotification } = useNotificationContext();
|
||||
const addWsUser = useAddUserToWs();
|
||||
|
||||
const { data: updateClosed } = useGetUserAction("jan_2024_db_update_closed");
|
||||
|
||||
const registerUserAction = useRegisterUserAction();
|
||||
const closeUpdate = async () => {
|
||||
await registerUserAction.mutateAsync("jan_2024_db_update_closed");
|
||||
};
|
||||
|
||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||
"addNewWs",
|
||||
"upgradePlan"
|
||||
@ -586,10 +595,10 @@ const OrganizationPage = withPermission(
|
||||
{!serverDetails?.redisConfigured && (
|
||||
<div className="mb-4 flex flex-col items-start justify-start px-6 py-6 pb-0 text-3xl">
|
||||
<p className="mr-4 mb-4 font-semibold text-white">Announcements</p>
|
||||
<div className="w-full border border-blue-400/70 rounded-md bg-blue-900/70 p-2 text-base text-mineshaft-100 flex items-center">
|
||||
<div className="flex w-full items-center rounded-md border border-blue-400/70 bg-blue-900/70 p-2 text-base text-mineshaft-100">
|
||||
<FontAwesomeIcon
|
||||
icon={faExclamationCircle}
|
||||
className="text-2xl mr-4 p-4 text-mineshaft-50"
|
||||
className="mr-4 p-4 text-2xl text-mineshaft-50"
|
||||
/>
|
||||
Attention: Updated versions of Infisical now require Redis for full functionality.
|
||||
Learn how to configure it
|
||||
@ -597,7 +606,7 @@ const OrganizationPage = withPermission(
|
||||
href="https://infisical.com/docs/self-hosting/configuration/redis"
|
||||
target="_blank"
|
||||
>
|
||||
<span className="pl-1 text-white underline underline-offset-2 hover:decoration-blue-400 hover:text-blue-200 duration-100 cursor-pointer">
|
||||
<span className="cursor-pointer pl-1 text-white underline underline-offset-2 duration-100 hover:text-blue-200 hover:decoration-blue-400">
|
||||
here
|
||||
</span>
|
||||
</Link>
|
||||
@ -606,6 +615,22 @@ const OrganizationPage = withPermission(
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-4 flex flex-col items-start justify-start px-6 py-6 pb-0 text-3xl">
|
||||
<div className={`${
|
||||
!updateClosed ? "block" : "hidden"
|
||||
} mb-4 w-full border rounded-md p-2 text-base border-primary-600 bg-primary/10 text-white flex flex-row items-center`}>
|
||||
<FontAwesomeIcon icon={faWarning} className="text-primary text-4xl p-6"/>
|
||||
<div className="text-sm">
|
||||
<span className="text-lg font-semibold">Scheduled maintenance on January 27th</span> <br />
|
||||
We've planned a database upgrade and need to pause certain functionality for approximately 3 hours on Saturday, January 27th, 10am EST. During these hours, read operations will continue to function normally but no resources will be editable. No action is required on your end — your applications can continue to fetch secrets.<br />
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => closeUpdate()}
|
||||
className="text-mineshaft-100 duration-200 hover:text-red-400 h-full flex items-start"
|
||||
>
|
||||
<FontAwesomeIcon icon={faXmark} />
|
||||
</button>
|
||||
</div>
|
||||
<p className="mr-4 font-semibold text-white">Projects</p>
|
||||
<div className="mt-6 flex w-full flex-row">
|
||||
<Input
|
||||
@ -701,7 +726,7 @@ const OrganizationPage = withPermission(
|
||||
</div>
|
||||
<div className="mb-4 flex flex-col items-start justify-start px-6 py-6 pb-6 text-3xl">
|
||||
<p className="mr-4 font-semibold text-white">Explore Infisical</p>
|
||||
<div className="mt-4 grid grid-cols-3 w-full gap-4">
|
||||
<div className="mt-4 grid w-full grid-cols-3 gap-4">
|
||||
{features.map((feature) => (
|
||||
<div
|
||||
key={feature._id}
|
||||
|
@ -61,7 +61,7 @@ export const SignUpPage = () => {
|
||||
router.push("/login");
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
}, [config?.initialized]);
|
||||
|
||||
const { mutateAsync: createAdminUser } = useCreateAdminUser();
|
||||
|
||||
@ -117,7 +117,7 @@ export const SignUpPage = () => {
|
||||
return <ContentLoader text="Redirecting to admin page..." />;
|
||||
|
||||
return (
|
||||
<div className="flex justify-center items-center">
|
||||
<div className="flex items-center justify-center">
|
||||
<AnimatePresence exitBeforeEnter>
|
||||
{step === SignupSteps.DetailsForm && (
|
||||
<motion.div
|
||||
@ -128,7 +128,7 @@ export const SignUpPage = () => {
|
||||
animate={{ opacity: 1, translateX: 0 }}
|
||||
exit={{ opacity: 0, translateX: 30 }}
|
||||
>
|
||||
<div className="text-center flex flex-col items-center space-y-4">
|
||||
<div className="flex flex-col items-center space-y-4 text-center">
|
||||
<img src="/images/gradientLogo.svg" height={90} width={120} alt="Infisical logo" />
|
||||
<div className="text-4xl">Welcome to Infisical</div>
|
||||
<div>Create your first Admin Account</div>
|
||||
|
Reference in New Issue
Block a user