mirror of
https://github.com/Infisical/infisical.git
synced 2025-07-18 01:29:25 +00:00
Compare commits
15 Commits
multi-inte
...
daniel/csh
Author | SHA1 | Date | |
---|---|---|---|
e88b0ad3c4 | |||
74644fd8bb | |||
2069ac1554 | |||
5a2516e0a7 | |||
b52bc3bed7 | |||
b815e3eb56 | |||
31231cfcca | |||
ee772e4a77 | |||
7bc29c5981 | |||
e9a89930da | |||
b85499859c | |||
7f17194c0f | |||
1e1ad450d2 | |||
45d96be1ff | |||
12840bfdbd |
@ -550,7 +550,7 @@ export const attachIdentityUniversalAuth = async (req: Request, res: Response) =
|
|||||||
|
|
||||||
// validate trusted ips
|
// validate trusted ips
|
||||||
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
|
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0") return res.status(400).send({
|
if (!plan.ipAllowlisting && (clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && clientSecretTrustedIp.ipAddress !== "::/0")) return res.status(400).send({
|
||||||
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -564,7 +564,7 @@ export const attachIdentityUniversalAuth = async (req: Request, res: Response) =
|
|||||||
});
|
});
|
||||||
|
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && accessTokenTrustedIp.ipAddress !== "0.0.0.0/0") return res.status(400).send({
|
if (!plan.ipAllowlisting && (accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" && accessTokenTrustedIp.ipAddress !== "::/0")) return res.status(400).send({
|
||||||
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -750,7 +750,7 @@ export const updateIdentityUniversalAuth = async (req: Request, res: Response) =
|
|||||||
let reformattedClientSecretTrustedIps;
|
let reformattedClientSecretTrustedIps;
|
||||||
if (clientSecretTrustedIps) {
|
if (clientSecretTrustedIps) {
|
||||||
reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
|
reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0") return res.status(400).send({
|
if (!plan.ipAllowlisting && (clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" && clientSecretTrustedIp.ipAddress !== "::/0")) return res.status(400).send({
|
||||||
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -767,7 +767,7 @@ export const updateIdentityUniversalAuth = async (req: Request, res: Response) =
|
|||||||
let reformattedAccessTokenTrustedIps;
|
let reformattedAccessTokenTrustedIps;
|
||||||
if (accessTokenTrustedIps) {
|
if (accessTokenTrustedIps) {
|
||||||
reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && accessTokenTrustedIp.ipAddress !== "0.0.0.0/0") return res.status(400).send({
|
if (!plan.ipAllowlisting && (accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" && accessTokenTrustedIp.ipAddress !== "::/0")) return res.status(400).send({
|
||||||
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
message: "Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
const {
|
const {
|
||||||
query: { secretPath, environment, workspaceId, type, include_imports },
|
query: { secretPath, environment, workspaceId, type, include_imports, version },
|
||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
|
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
|
||||||
|
|
||||||
@ -371,7 +371,8 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
|
|||||||
type,
|
type,
|
||||||
secretPath,
|
secretPath,
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
include_imports
|
include_imports,
|
||||||
|
version
|
||||||
});
|
});
|
||||||
|
|
||||||
const key = await BotService.getWorkspaceKeyWithBot({
|
const key = await BotService.getWorkspaceKeyWithBot({
|
||||||
@ -865,7 +866,7 @@ export const getSecrets = async (req: Request, res: Response) => {
|
|||||||
*/
|
*/
|
||||||
export const getSecretByName = async (req: Request, res: Response) => {
|
export const getSecretByName = async (req: Request, res: Response) => {
|
||||||
const {
|
const {
|
||||||
query: { secretPath, environment, workspaceId, type, include_imports },
|
query: { secretPath, environment, workspaceId, type, include_imports, version },
|
||||||
params: { secretName }
|
params: { secretName }
|
||||||
} = await validateRequest(reqValidator.GetSecretByNameV3, req);
|
} = await validateRequest(reqValidator.GetSecretByNameV3, req);
|
||||||
|
|
||||||
@ -888,7 +889,8 @@ export const getSecretByName = async (req: Request, res: Response) => {
|
|||||||
type,
|
type,
|
||||||
secretPath,
|
secretPath,
|
||||||
authData: req.authData,
|
authData: req.authData,
|
||||||
include_imports
|
include_imports,
|
||||||
|
version
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
|
@ -611,42 +611,81 @@ export const getSecretHelper = async ({
|
|||||||
type,
|
type,
|
||||||
authData,
|
authData,
|
||||||
secretPath = "/",
|
secretPath = "/",
|
||||||
include_imports = true
|
include_imports = true,
|
||||||
|
version
|
||||||
}: GetSecretParams) => {
|
}: GetSecretParams) => {
|
||||||
|
|
||||||
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
||||||
secretName,
|
secretName,
|
||||||
workspaceId: new Types.ObjectId(workspaceId)
|
workspaceId: new Types.ObjectId(workspaceId)
|
||||||
});
|
});
|
||||||
let secret: ISecret | null | undefined = null;
|
let secret: ISecret | null | undefined = null;
|
||||||
|
|
||||||
// if using service token filter towards the folderId by secretpath
|
// if using service token filter towards the folderId by secretpath
|
||||||
|
|
||||||
const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath);
|
const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath);
|
||||||
|
|
||||||
// try getting personal secret first (if exists)
|
// try getting personal secret first (if exists)
|
||||||
secret = await Secret.findOne({
|
if (version === undefined) {
|
||||||
secretBlindIndex,
|
|
||||||
workspace: new Types.ObjectId(workspaceId),
|
|
||||||
environment,
|
|
||||||
folder: folderId,
|
|
||||||
type: type ?? SECRET_PERSONAL,
|
|
||||||
...(type === SECRET_PERSONAL ? getAuthDataPayloadUserObj(authData) : {})
|
|
||||||
}).lean();
|
|
||||||
|
|
||||||
if (!secret) {
|
|
||||||
// case: failed to find personal secret matching criteria
|
|
||||||
// -> find shared secret matching criteria
|
|
||||||
secret = await Secret.findOne({
|
secret = await Secret.findOne({
|
||||||
secretBlindIndex,
|
secretBlindIndex,
|
||||||
workspace: new Types.ObjectId(workspaceId),
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
environment,
|
environment,
|
||||||
folder: folderId,
|
folder: folderId,
|
||||||
type: SECRET_SHARED
|
type: type ?? SECRET_PERSONAL,
|
||||||
|
...(type === SECRET_PERSONAL ? getAuthDataPayloadUserObj(authData) : {})
|
||||||
}).lean();
|
}).lean();
|
||||||
|
} else {
|
||||||
|
const secretVersion = await SecretVersion.findOne({
|
||||||
|
secretBlindIndex,
|
||||||
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
|
environment,
|
||||||
|
folder: folderId,
|
||||||
|
type: type ?? SECRET_PERSONAL,
|
||||||
|
version
|
||||||
|
}).lean();
|
||||||
|
|
||||||
|
if (secretVersion) {
|
||||||
|
secret = await new Secret({
|
||||||
|
...secretVersion,
|
||||||
|
_id: secretVersion?.secret
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!secret) {
|
||||||
|
// case: failed to find personal secret matching criteria
|
||||||
|
// -> find shared secret matching criteria
|
||||||
|
if (version === undefined) {
|
||||||
|
secret = await Secret.findOne({
|
||||||
|
secretBlindIndex,
|
||||||
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
|
environment,
|
||||||
|
folder: folderId,
|
||||||
|
type: SECRET_SHARED
|
||||||
|
}).lean();
|
||||||
|
} else {
|
||||||
|
const secretVersion = await SecretVersion.findOne({
|
||||||
|
secretBlindIndex,
|
||||||
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
|
environment,
|
||||||
|
folder: folderId,
|
||||||
|
type: SECRET_SHARED,
|
||||||
|
version
|
||||||
|
}).lean();
|
||||||
|
|
||||||
|
if (secretVersion) {
|
||||||
|
secret = await new Secret({
|
||||||
|
...secretVersion,
|
||||||
|
_id: secretVersion?.secret
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!secret && include_imports) {
|
if (!secret && include_imports) {
|
||||||
// if still no secret found search in imported secret and retreive
|
// if still no secret found search in imported secret and retreive
|
||||||
secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId);
|
secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!secret) throw SecretNotFoundError();
|
if (!secret) throw SecretNotFoundError();
|
||||||
|
@ -38,6 +38,7 @@ export interface GetSecretParams {
|
|||||||
type?: "shared" | "personal";
|
type?: "shared" | "personal";
|
||||||
authData: AuthData;
|
authData: AuthData;
|
||||||
include_imports?: boolean;
|
include_imports?: boolean;
|
||||||
|
version?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateSecretParams {
|
export interface UpdateSecretParams {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { Types } from "mongoose";
|
import { Types } from "mongoose";
|
||||||
import { generateSecretBlindIndexHelper } from "../helpers";
|
import { generateSecretBlindIndexHelper } from "../helpers";
|
||||||
|
import { SecretVersion } from "../ee/models";
|
||||||
import { Folder, ISecret, Secret, SecretImport } from "../models";
|
import { Folder, ISecret, Secret, SecretImport } from "../models";
|
||||||
import { getFolderByPath } from "./FolderService";
|
import { getFolderByPath } from "./FolderService";
|
||||||
|
|
||||||
@ -9,7 +10,8 @@ export const getAnImportedSecret = async (
|
|||||||
secretName: string,
|
secretName: string,
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
environment: string,
|
environment: string,
|
||||||
folderId = "root"
|
folderId = "root",
|
||||||
|
version?: number
|
||||||
) => {
|
) => {
|
||||||
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
const secretBlindIndex = await generateSecretBlindIndexHelper({
|
||||||
secretName,
|
secretName,
|
||||||
@ -48,10 +50,26 @@ export const getAnImportedSecret = async (
|
|||||||
});
|
});
|
||||||
if (importedSecByFid.length === 0) return;
|
if (importedSecByFid.length === 0) return;
|
||||||
|
|
||||||
const secret = await Secret.findOne({
|
let secret;
|
||||||
workspace: workspaceId,
|
if (version === undefined) {
|
||||||
secretBlindIndex
|
secret = await Secret.findOne({
|
||||||
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId }))).lean()
|
workspace: workspaceId,
|
||||||
|
secretBlindIndex
|
||||||
|
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId }))).lean()
|
||||||
|
} else {
|
||||||
|
const secretVersion = await SecretVersion.findOne({
|
||||||
|
workspace: workspaceId,
|
||||||
|
secretBlindIndex,
|
||||||
|
version
|
||||||
|
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId }))).lean();
|
||||||
|
|
||||||
|
if (secretVersion) {
|
||||||
|
secret = await new Secret({
|
||||||
|
...secretVersion,
|
||||||
|
_id: secretVersion.secret,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return secret;
|
return secret;
|
||||||
};
|
};
|
||||||
|
@ -108,14 +108,14 @@ export const AddUniversalAuthToIdentityV1 = z.object({
|
|||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
.min(1)
|
.min(1)
|
||||||
.default([{ ipAddress: "0.0.0.0/0" }]),
|
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
|
||||||
accessTokenTrustedIps: z
|
accessTokenTrustedIps: z
|
||||||
.object({
|
.object({
|
||||||
ipAddress: z.string().trim(),
|
ipAddress: z.string().trim(),
|
||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
.min(1)
|
.min(1)
|
||||||
.default([{ ipAddress: "0.0.0.0/0" }]),
|
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
|
||||||
accessTokenTTL: z.number().int().min(1).refine(value => value !== 0, {
|
accessTokenTTL: z.number().int().min(1).refine(value => value !== 0, {
|
||||||
message: "accessTokenTTL must have a non zero number",
|
message: "accessTokenTTL must have a non zero number",
|
||||||
}).default(2592000),
|
}).default(2592000),
|
||||||
|
@ -246,7 +246,15 @@ export const GetSecretByNameRawV3 = z.object({
|
|||||||
include_imports: z
|
include_imports: z
|
||||||
.enum(["true", "false"])
|
.enum(["true", "false"])
|
||||||
.default("true")
|
.default("true")
|
||||||
.transform((value) => value === "true")
|
.transform((value) => value === "true"),
|
||||||
|
version: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.optional()
|
||||||
|
.transform((value) => value === undefined ? undefined : parseInt(value, 10))
|
||||||
|
.refine((value) => value === undefined || !isNaN(value), {
|
||||||
|
message: "Version must be a number",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -318,7 +326,15 @@ export const GetSecretByNameV3 = z.object({
|
|||||||
include_imports: z
|
include_imports: z
|
||||||
.enum(["true", "false"])
|
.enum(["true", "false"])
|
||||||
.default("true")
|
.default("true")
|
||||||
.transform((value) => value === "true")
|
.transform((value) => value === "true"),
|
||||||
|
version: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.optional()
|
||||||
|
.transform((value) => value === undefined ? undefined : parseInt(value, 10))
|
||||||
|
.refine((value) => value === undefined || !isNaN(value), {
|
||||||
|
message: "Version must be a number",
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
params: z.object({
|
params: z.object({
|
||||||
secretName: z.string().trim()
|
secretName: z.string().trim()
|
||||||
|
@ -5,6 +5,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -37,7 +38,8 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type InfisicalConfig struct {
|
type InfisicalConfig struct {
|
||||||
Address string `yaml:"address"`
|
Address string `yaml:"address"`
|
||||||
|
ExitAfterAuth bool `yaml:"exit-after-auth"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthConfig struct {
|
type AuthConfig struct {
|
||||||
@ -66,8 +68,9 @@ type SinkDetails struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Template struct {
|
type Template struct {
|
||||||
SourcePath string `yaml:"source-path"`
|
SourcePath string `yaml:"source-path"`
|
||||||
DestinationPath string `yaml:"destination-path"`
|
Base64TemplateContent string `yaml:"base64-template-content"`
|
||||||
|
DestinationPath string `yaml:"destination-path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadFile(filePath string) ([]byte, error) {
|
func ReadFile(filePath string) ([]byte, error) {
|
||||||
@ -107,12 +110,7 @@ func appendAPIEndpoint(address string) string {
|
|||||||
return address + "/api"
|
return address + "/api"
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAgentConfig(filePath string) (*Config, error) {
|
func ParseAgentConfig(configFile []byte) (*Config, error) {
|
||||||
data, err := ioutil.ReadFile(filePath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var rawConfig struct {
|
var rawConfig struct {
|
||||||
Infisical InfisicalConfig `yaml:"infisical"`
|
Infisical InfisicalConfig `yaml:"infisical"`
|
||||||
Auth struct {
|
Auth struct {
|
||||||
@ -123,7 +121,7 @@ func ParseAgentConfig(filePath string) (*Config, error) {
|
|||||||
Templates []Template `yaml:"templates"`
|
Templates []Template `yaml:"templates"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := yaml.Unmarshal(data, &rawConfig); err != nil {
|
if err := yaml.Unmarshal(configFile, &rawConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,6 +203,35 @@ func ProcessTemplate(templatePath string, data interface{}, accessToken string)
|
|||||||
return &buf, nil
|
return &buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProcessBase64Template(encodedTemplate string, data interface{}, accessToken string) (*bytes.Buffer, error) {
|
||||||
|
// custom template function to fetch secrets from Infisical
|
||||||
|
decoded, err := base64.StdEncoding.DecodeString(encodedTemplate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
templateString := string(decoded)
|
||||||
|
|
||||||
|
secretFunction := secretTemplateFunction(accessToken)
|
||||||
|
funcs := template.FuncMap{
|
||||||
|
"secret": secretFunction,
|
||||||
|
}
|
||||||
|
|
||||||
|
templateName := "base64Template"
|
||||||
|
|
||||||
|
tmpl, err := template.New(templateName).Funcs(funcs).Parse(templateString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := tmpl.Execute(&buf, data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &buf, nil
|
||||||
|
}
|
||||||
|
|
||||||
type TokenManager struct {
|
type TokenManager struct {
|
||||||
accessToken string
|
accessToken string
|
||||||
accessTokenTTL time.Duration
|
accessTokenTTL time.Duration
|
||||||
@ -219,10 +246,11 @@ type TokenManager struct {
|
|||||||
newAccessTokenNotificationChan chan bool
|
newAccessTokenNotificationChan chan bool
|
||||||
removeClientSecretOnRead bool
|
removeClientSecretOnRead bool
|
||||||
cachedClientSecret string
|
cachedClientSecret string
|
||||||
|
exitAfterAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTokenManager(fileDeposits []Sink, templates []Template, clientIdPath string, clientSecretPath string, newAccessTokenNotificationChan chan bool, removeClientSecretOnRead bool) *TokenManager {
|
func NewTokenManager(fileDeposits []Sink, templates []Template, clientIdPath string, clientSecretPath string, newAccessTokenNotificationChan chan bool, removeClientSecretOnRead bool, exitAfterAuth bool) *TokenManager {
|
||||||
return &TokenManager{filePaths: fileDeposits, templates: templates, clientIdPath: clientIdPath, clientSecretPath: clientSecretPath, newAccessTokenNotificationChan: newAccessTokenNotificationChan, removeClientSecretOnRead: removeClientSecretOnRead}
|
return &TokenManager{filePaths: fileDeposits, templates: templates, clientIdPath: clientIdPath, clientSecretPath: clientSecretPath, newAccessTokenNotificationChan: newAccessTokenNotificationChan, removeClientSecretOnRead: removeClientSecretOnRead, exitAfterAuth: exitAfterAuth}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tm *TokenManager) SetToken(token string, accessTokenTTL time.Duration, accessTokenMaxTTL time.Duration) {
|
func (tm *TokenManager) SetToken(token string, accessTokenTTL time.Duration, accessTokenMaxTTL time.Duration) {
|
||||||
@ -245,18 +273,26 @@ func (tm *TokenManager) GetToken() string {
|
|||||||
|
|
||||||
// Fetches a new access token using client credentials
|
// Fetches a new access token using client credentials
|
||||||
func (tm *TokenManager) FetchNewAccessToken() error {
|
func (tm *TokenManager) FetchNewAccessToken() error {
|
||||||
clientIDAsByte, err := ReadFile(tm.clientIdPath)
|
clientID := os.Getenv("INFISICAL_UNIVERSAL_AUTH_CLIENT_ID")
|
||||||
if err != nil {
|
if clientID == "" {
|
||||||
return fmt.Errorf("unable to read client id from file path '%s' due to error: %v", tm.clientIdPath, err)
|
clientIDAsByte, err := ReadFile(tm.clientIdPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read client id from file path '%s' due to error: %v", tm.clientIdPath, err)
|
||||||
|
}
|
||||||
|
clientID = string(clientIDAsByte)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientSecretAsByte, err := ReadFile(tm.clientSecretPath)
|
clientSecret := os.Getenv("INFISICAL_UNIVERSAL_CLIENT_SECRET")
|
||||||
if err != nil {
|
if clientSecret == "" {
|
||||||
if len(tm.cachedClientSecret) == 0 {
|
clientSecretAsByte, err := ReadFile(tm.clientSecretPath)
|
||||||
return fmt.Errorf("unable to read client secret from file and no cached client secret found: %v", err)
|
if err != nil {
|
||||||
} else {
|
if len(tm.cachedClientSecret) == 0 {
|
||||||
clientSecretAsByte = []byte(tm.cachedClientSecret)
|
return fmt.Errorf("unable to read client secret from file and no cached client secret found: %v", err)
|
||||||
|
} else {
|
||||||
|
clientSecretAsByte = []byte(tm.cachedClientSecret)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
clientSecret = string(clientSecretAsByte)
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove client secret after first read
|
// remove client secret after first read
|
||||||
@ -264,13 +300,10 @@ func (tm *TokenManager) FetchNewAccessToken() error {
|
|||||||
os.Remove(tm.clientSecretPath)
|
os.Remove(tm.clientSecretPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientId := string(clientIDAsByte)
|
|
||||||
clientSecret := string(clientSecretAsByte)
|
|
||||||
|
|
||||||
// save as cache in memory
|
// save as cache in memory
|
||||||
tm.cachedClientSecret = clientSecret
|
tm.cachedClientSecret = clientSecret
|
||||||
|
|
||||||
err, loginResponse := universalAuthLogin(clientId, clientSecret)
|
err, loginResponse := universalAuthLogin(clientID, clientSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -354,6 +387,11 @@ func (tm *TokenManager) ManageTokenLifecycle() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tm.exitAfterAuth {
|
||||||
|
time.Sleep(25 * time.Second)
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
if accessTokenRefreshedTime.IsZero() {
|
if accessTokenRefreshedTime.IsZero() {
|
||||||
accessTokenRefreshedTime = tm.accessTokenFetchedTime
|
accessTokenRefreshedTime = tm.accessTokenFetchedTime
|
||||||
} else {
|
} else {
|
||||||
@ -396,7 +434,14 @@ func (tm *TokenManager) FetchSecrets() {
|
|||||||
token := tm.GetToken()
|
token := tm.GetToken()
|
||||||
if token != "" {
|
if token != "" {
|
||||||
for _, secretTemplate := range tm.templates {
|
for _, secretTemplate := range tm.templates {
|
||||||
processedTemplate, err := ProcessTemplate(secretTemplate.SourcePath, nil, token)
|
var processedTemplate *bytes.Buffer
|
||||||
|
var err error
|
||||||
|
if secretTemplate.SourcePath != "" {
|
||||||
|
processedTemplate, err = ProcessTemplate(secretTemplate.SourcePath, nil, token)
|
||||||
|
} else {
|
||||||
|
processedTemplate, err = ProcessBase64Template(secretTemplate.Base64TemplateContent, nil, token)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msgf("template engine: unable to render secrets because %s. Will try again on next cycle", err)
|
log.Error().Msgf("template engine: unable to render secrets because %s. Will try again on next cycle", err)
|
||||||
|
|
||||||
@ -449,12 +494,38 @@ var agentCmd = &cobra.Command{
|
|||||||
util.HandleError(err, "Unable to parse flag config")
|
util.HandleError(err, "Unable to parse flag config")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !FileExists(configPath) {
|
var agentConfigInBytes []byte
|
||||||
log.Error().Msgf("Unable to locate %s. The provided agent config file path is either missing or incorrect", configPath)
|
|
||||||
|
agentConfigInBase64 := os.Getenv("INFISICAL_AGENT_CONFIG_BASE64")
|
||||||
|
|
||||||
|
if configPath != "" {
|
||||||
|
data, err := ioutil.ReadFile(configPath)
|
||||||
|
if err != nil {
|
||||||
|
if !FileExists(configPath) {
|
||||||
|
log.Error().Msgf("Unable to locate %s. The provided agent config file path is either missing or incorrect", configPath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
agentConfigInBytes = data
|
||||||
|
}
|
||||||
|
|
||||||
|
if agentConfigInBase64 != "" {
|
||||||
|
decodedAgentConfig, err := base64.StdEncoding.DecodeString(agentConfigInBase64)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Msgf("Unable to decode base64 config file because %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
agentConfigInBytes = decodedAgentConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
if !FileExists(configPath) && agentConfigInBase64 == "" {
|
||||||
|
log.Error().Msgf("No agent config file provided. Please provide a agent config file", configPath)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
agentConfig, err := ParseAgentConfig(configPath)
|
agentConfig, err := ParseAgentConfig(agentConfigInBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msgf("Unable to prase %s because %v. Please ensure that is follows the Infisical Agent config structure", configPath, err)
|
log.Error().Msgf("Unable to prase %s because %v. Please ensure that is follows the Infisical Agent config structure", configPath, err)
|
||||||
return
|
return
|
||||||
@ -471,7 +542,7 @@ var agentCmd = &cobra.Command{
|
|||||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
filePaths := agentConfig.Sinks
|
filePaths := agentConfig.Sinks
|
||||||
tm := NewTokenManager(filePaths, agentConfig.Templates, configUniversalAuthType.ClientIDPath, configUniversalAuthType.ClientSecretPath, tokenRefreshNotifier, configUniversalAuthType.RemoveClientSecretOnRead)
|
tm := NewTokenManager(filePaths, agentConfig.Templates, configUniversalAuthType.ClientIDPath, configUniversalAuthType.ClientSecretPath, tokenRefreshNotifier, configUniversalAuthType.RemoveClientSecretOnRead, agentConfig.Infisical.ExitAfterAuth)
|
||||||
|
|
||||||
go tm.ManageTokenLifecycle()
|
go tm.ManageTokenLifecycle()
|
||||||
go tm.FetchSecrets()
|
go tm.FetchSecrets()
|
||||||
|
@ -76,7 +76,7 @@ If the command handler fails to validate the input, an error will be returned to
|
|||||||
|
|
||||||
|
|
||||||
<Frame caption="Execution flow diagram for the SDK from the target language to the base SDK. The execution flow is the same for all target languages.">
|
<Frame caption="Execution flow diagram for the SDK from the target language to the base SDK. The execution flow is the same for all target languages.">
|
||||||
<img height="640" width="520" src="images/sdk-flow.png" />
|
<img height="640" width="520" src="/images/sdk-flow.png" />
|
||||||
</Frame>
|
</Frame>
|
||||||
|
|
||||||
|
|
||||||
|
391
docs/sdks/languages/csharp.mdx
Normal file
391
docs/sdks/languages/csharp.mdx
Normal file
@ -0,0 +1,391 @@
|
|||||||
|
---
|
||||||
|
title: "C#"
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 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.
|
|
@ -121,7 +121,7 @@ SecretElement[] secrets = client.listSecrets(options);
|
|||||||
|
|
||||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||||
|
|
||||||
### Methods
|
#### Methods
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object">
|
<ParamField query="Parameters" type="object">
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -165,7 +165,7 @@ Retrieve a secret from Infisical.
|
|||||||
|
|
||||||
By default, `getSecret()` fetches and returns a shared secret.
|
By default, `getSecret()` fetches and returns a shared secret.
|
||||||
|
|
||||||
### Methods
|
#### Methods
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -203,7 +203,7 @@ CreateSecretResponseSecret newSecret = client.createSecret(createOptions);
|
|||||||
|
|
||||||
Create a new secret in Infisical.
|
Create a new secret in Infisical.
|
||||||
|
|
||||||
### Methods
|
#### Methods
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -245,7 +245,7 @@ UpdateSecretResponseSecret updatedSecret = client.updateSecret(options);
|
|||||||
|
|
||||||
Update an existing secret in Infisical.
|
Update an existing secret in Infisical.
|
||||||
|
|
||||||
### Methods
|
#### Methods
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -286,7 +286,7 @@ DeleteSecretResponseSecret deletedSecret = client.deleteSecret(options);
|
|||||||
|
|
||||||
Delete a secret in Infisical.
|
Delete a secret in Infisical.
|
||||||
|
|
||||||
### Methods
|
#### Methods
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -307,3 +307,76 @@ Delete a secret in Infisical.
|
|||||||
</ParamField>
|
</ParamField>
|
||||||
</Expandable>
|
</Expandable>
|
||||||
</ParamField>
|
</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.
|
@ -84,12 +84,12 @@ Import the SDK and create a client instance with your [Machine Identity](/docume
|
|||||||
clientSecret: "YOUR_CLIENT_SECRET",
|
clientSecret: "YOUR_CLIENT_SECRET",
|
||||||
logLevel: LogLevel.Error
|
logLevel: LogLevel.Error
|
||||||
});
|
});
|
||||||
````
|
```
|
||||||
|
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="options" type="object">
|
<ParamField query="options" type="object">
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -138,7 +138,7 @@ const secrets = await client.listSecrets({
|
|||||||
|
|
||||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object">
|
<ParamField query="Parameters" type="object">
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -180,7 +180,7 @@ Retrieve a secret from Infisical.
|
|||||||
|
|
||||||
By default, `getSecret()` fetches and returns a shared secret.
|
By default, `getSecret()` fetches and returns a shared secret.
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -255,7 +255,7 @@ const updatedApiKey = await client.updateSecret({
|
|||||||
|
|
||||||
Update an existing secret in Infisical.
|
Update an existing secret in Infisical.
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -315,3 +315,73 @@ Delete a secret in Infisical.
|
|||||||
</ParamField>
|
</ParamField>
|
||||||
</Expandable>
|
</Expandable>
|
||||||
</ParamField>
|
</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.
|
|
@ -60,7 +60,7 @@ client = InfisicalClient(ClientSettings(
|
|||||||
))
|
))
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="options" type="object">
|
<ParamField query="options" type="object">
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -110,7 +110,7 @@ client.listSecrets(options=ListSecretsOptions(
|
|||||||
|
|
||||||
Retrieve all secrets within the Infisical project and environment that client is connected to
|
Retrieve all secrets within the Infisical project and environment that client is connected to
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object">
|
<ParamField query="Parameters" type="object">
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -149,7 +149,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.
|
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>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -187,7 +187,7 @@ api_key = client.createSecret(options=CreateSecretOptions(
|
|||||||
|
|
||||||
Create a new secret in Infisical.
|
Create a new secret in Infisical.
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -225,7 +225,7 @@ client.updateSecret(options=UpdateSecretOptions(
|
|||||||
|
|
||||||
Update an existing secret in Infisical.
|
Update an existing secret in Infisical.
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -262,7 +262,7 @@ client.deleteSecret(options=DeleteSecretOptions(
|
|||||||
|
|
||||||
Delete a secret in Infisical.
|
Delete a secret in Infisical.
|
||||||
|
|
||||||
### Parameters
|
#### Parameters
|
||||||
|
|
||||||
<ParamField query="Parameters" type="object" optional>
|
<ParamField query="Parameters" type="object" optional>
|
||||||
<Expandable title="properties">
|
<Expandable title="properties">
|
||||||
@ -283,3 +283,79 @@ Delete a secret in Infisical.
|
|||||||
</ParamField>
|
</ParamField>
|
||||||
</Expandable>
|
</Expandable>
|
||||||
</ParamField>
|
</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">
|
<Card href="/sdks/languages/java" title="Java" icon="java" color="#e41f23">
|
||||||
Manage secrets for your Java application on demand
|
Manage secrets for your Java application on demand
|
||||||
</Card>
|
</Card>
|
||||||
<Card href="/sdks/languages/ruby" title="Ruby" icon="gem" color="#ac0d01">
|
<Card href="/sdks/languages/csharp" title="C#" icon="bars" color="#368833">
|
||||||
Manage secrets for your Ruby application on demand
|
Manage secrets for your C#/.NET 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>
|
</Card>
|
||||||
</CardGroup>
|
</CardGroup>
|
||||||
|
|
||||||
|
@ -91,12 +91,14 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
accessTokenTTL: "2592000",
|
accessTokenTTL: "2592000",
|
||||||
accessTokenMaxTTL: "2592000",
|
accessTokenMaxTTL: "2592000",
|
||||||
accessTokenNumUsesLimit: "0",
|
accessTokenNumUsesLimit: "0",
|
||||||
clientSecretTrustedIps: [{
|
clientSecretTrustedIps: [
|
||||||
ipAddress: "0.0.0.0/0"
|
{ ipAddress: "0.0.0.0/0" },
|
||||||
}],
|
{ ipAddress: "::/0" }
|
||||||
accessTokenTrustedIps: [{
|
],
|
||||||
ipAddress: "0.0.0.0/0"
|
accessTokenTrustedIps: [
|
||||||
}],
|
{ ipAddress: "0.0.0.0/0" },
|
||||||
|
{ ipAddress: "::/0" }
|
||||||
|
],
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -139,12 +141,14 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
accessTokenTTL: "2592000",
|
accessTokenTTL: "2592000",
|
||||||
accessTokenMaxTTL: "2592000",
|
accessTokenMaxTTL: "2592000",
|
||||||
accessTokenNumUsesLimit: "0",
|
accessTokenNumUsesLimit: "0",
|
||||||
clientSecretTrustedIps: [{
|
clientSecretTrustedIps: [
|
||||||
ipAddress: "0.0.0.0/0"
|
{ ipAddress: "0.0.0.0/0" },
|
||||||
}],
|
{ ipAddress: "::/0" }
|
||||||
accessTokenTrustedIps: [{
|
],
|
||||||
ipAddress: "0.0.0.0/0"
|
accessTokenTrustedIps: [
|
||||||
}]
|
{ ipAddress: "0.0.0.0/0" },
|
||||||
|
{ ipAddress: "::/0" }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
Reference in New Issue
Block a user