Add service account support for organization endpoints and update docs images
@@ -22,8 +22,8 @@ const validateMembershipOrg = async ({
|
|||||||
}: {
|
}: {
|
||||||
userId: Types.ObjectId;
|
userId: Types.ObjectId;
|
||||||
organizationId: Types.ObjectId;
|
organizationId: Types.ObjectId;
|
||||||
acceptedRoles: string[];
|
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
|
||||||
acceptedStatuses: string[];
|
acceptedStatuses: Array<'invited' | 'accepted'>;
|
||||||
}) => {
|
}) => {
|
||||||
const membershipOrg = await MembershipOrg.findOne({
|
const membershipOrg = await MembershipOrg.findOne({
|
||||||
user: userId,
|
user: userId,
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import {
|
|||||||
AUTH_MODE_JWT,
|
AUTH_MODE_JWT,
|
||||||
AUTH_MODE_SERVICE_ACCOUNT,
|
AUTH_MODE_SERVICE_ACCOUNT,
|
||||||
AUTH_MODE_SERVICE_TOKEN,
|
AUTH_MODE_SERVICE_TOKEN,
|
||||||
AUTH_MODE_API_KEY
|
AUTH_MODE_API_KEY,
|
||||||
|
OWNER
|
||||||
} from '../variables';
|
} from '../variables';
|
||||||
import {
|
import {
|
||||||
getStripeSecretKey,
|
getStripeSecretKey,
|
||||||
@@ -24,8 +25,15 @@ import {
|
|||||||
getStripeProductStarter
|
getStripeProductStarter
|
||||||
} from '../config';
|
} from '../config';
|
||||||
import {
|
import {
|
||||||
UnauthorizedRequestError
|
UnauthorizedRequestError,
|
||||||
|
OrganizationNotFoundError
|
||||||
} from '../utils/errors';
|
} from '../utils/errors';
|
||||||
|
import {
|
||||||
|
validateUserClientForOrganization
|
||||||
|
} from '../helpers/user';
|
||||||
|
import {
|
||||||
|
validateServiceAccountClientForOrganization
|
||||||
|
} from '../helpers/serviceAccount';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate accepted clients for organization with id [organizationId]
|
* Validate accepted clients for organization with id [organizationId]
|
||||||
@@ -35,30 +43,62 @@ import {
|
|||||||
*/
|
*/
|
||||||
const validateClientForOrganization = async ({
|
const validateClientForOrganization = async ({
|
||||||
authData,
|
authData,
|
||||||
organizationId
|
organizationId,
|
||||||
|
acceptedRoles,
|
||||||
|
acceptedStatuses
|
||||||
}: {
|
}: {
|
||||||
authData: {
|
authData: {
|
||||||
authMode: string;
|
authMode: string;
|
||||||
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
authPayload: IUser | IServiceAccount | IServiceTokenData;
|
||||||
},
|
},
|
||||||
organizationId: string;
|
organizationId: Types.ObjectId;
|
||||||
|
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
|
||||||
|
acceptedStatuses: Array<'invited' | 'accepted'>;
|
||||||
}) => {
|
}) => {
|
||||||
// TODO
|
|
||||||
|
const organization = await Organization.findById(organizationId);
|
||||||
|
|
||||||
|
if (!organization) {
|
||||||
|
throw OrganizationNotFoundError({
|
||||||
|
message: 'Failed to find organization'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
|
||||||
// TODO
|
const membershipOrg = await validateUserClientForOrganization({
|
||||||
|
user: authData.authPayload,
|
||||||
|
organization,
|
||||||
|
acceptedRoles,
|
||||||
|
acceptedStatuses
|
||||||
|
});
|
||||||
|
|
||||||
|
return ({ organization, membershipOrg });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
|
||||||
// TODO
|
await validateServiceAccountClientForOrganization({
|
||||||
|
serviceAccount: authData.authPayload,
|
||||||
|
organization
|
||||||
|
});
|
||||||
|
|
||||||
|
return ({ organization });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
|
||||||
// TODO
|
throw UnauthorizedRequestError({
|
||||||
|
message: 'Failed service token authorization for organization resource'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
|
||||||
// TODO
|
const membershipOrg = await validateUserClientForOrganization({
|
||||||
|
user: authData.authPayload,
|
||||||
|
organization,
|
||||||
|
acceptedRoles,
|
||||||
|
acceptedStatuses
|
||||||
|
});
|
||||||
|
|
||||||
|
return ({ organization, membershipOrg });
|
||||||
}
|
}
|
||||||
|
|
||||||
throw UnauthorizedRequestError({
|
throw UnauthorizedRequestError({
|
||||||
@@ -228,6 +268,7 @@ const updateSubscriptionOrgQuantity = async ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
validateClientForOrganization,
|
||||||
createOrganization,
|
createOrganization,
|
||||||
initSubscriptionOrg,
|
initSubscriptionOrg,
|
||||||
updateSubscriptionOrgQuantity
|
updateSubscriptionOrgQuantity
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
ServiceTokenData,
|
ServiceTokenData,
|
||||||
IServiceTokenData,
|
IServiceTokenData,
|
||||||
ISecret,
|
ISecret,
|
||||||
|
IOrganization,
|
||||||
ServiceAccountWorkspacePermission
|
ServiceAccountWorkspacePermission
|
||||||
} from '../models';
|
} from '../models';
|
||||||
import {
|
import {
|
||||||
@@ -109,9 +110,6 @@ const validateClientForServiceAccount = async ({
|
|||||||
environment?: string;
|
environment?: string;
|
||||||
requiredPermissions?: string[];
|
requiredPermissions?: string[];
|
||||||
}) => {
|
}) => {
|
||||||
// TODO: add service account API support for workspace-level endpoints that are not
|
|
||||||
// tied to any specific environment
|
|
||||||
|
|
||||||
if (environment) {
|
if (environment) {
|
||||||
const permission = await ServiceAccountWorkspacePermission.findOne({
|
const permission = await ServiceAccountWorkspacePermission.findOne({
|
||||||
serviceAccount,
|
serviceAccount,
|
||||||
@@ -123,7 +121,6 @@ const validateClientForServiceAccount = async ({
|
|||||||
message: 'Failed service account authorization for the given workspace environment'
|
message: 'Failed service account authorization for the given workspace environment'
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
let runningIsDisallowed = false;
|
let runningIsDisallowed = false;
|
||||||
requiredPermissions?.forEach((requiredPermission: string) => {
|
requiredPermissions?.forEach((requiredPermission: string) => {
|
||||||
switch (requiredPermission) {
|
switch (requiredPermission) {
|
||||||
@@ -180,7 +177,6 @@ const validateClientForServiceAccount = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
requiredPermissions?.forEach((requiredPermission: string) => {
|
requiredPermissions?.forEach((requiredPermission: string) => {
|
||||||
// TODO: refactor
|
|
||||||
let runningIsDisallowed = false;
|
let runningIsDisallowed = false;
|
||||||
requiredPermissions?.forEach((requiredPermission: string) => {
|
requiredPermissions?.forEach((requiredPermission: string) => {
|
||||||
switch (requiredPermission) {
|
switch (requiredPermission) {
|
||||||
@@ -202,9 +198,6 @@ const validateClientForServiceAccount = async ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -231,9 +224,30 @@ const validateServiceAccountClientForServiceAccount = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that service account (client) can access organization [organization]
|
||||||
|
* @param {Object} obj
|
||||||
|
* @param {User} obj.user - service account client
|
||||||
|
* @param {Organization} obj.organization - organization to validate against
|
||||||
|
*/
|
||||||
|
const validateServiceAccountClientForOrganization = async ({
|
||||||
|
serviceAccount,
|
||||||
|
organization
|
||||||
|
}: {
|
||||||
|
serviceAccount: IServiceAccount;
|
||||||
|
organization: IOrganization;
|
||||||
|
}) => {
|
||||||
|
if (!serviceAccount.organization.equals(organization._id)) {
|
||||||
|
throw UnauthorizedRequestError({
|
||||||
|
message: 'Failed service account authorization for the given organization'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
validateClientForServiceAccount,
|
validateClientForServiceAccount,
|
||||||
validateServiceAccountClientForWorkspace,
|
validateServiceAccountClientForWorkspace,
|
||||||
validateServiceAccountClientForSecrets,
|
validateServiceAccountClientForSecrets,
|
||||||
validateServiceAccountClientForServiceAccount
|
validateServiceAccountClientForServiceAccount,
|
||||||
|
validateServiceAccountClientForOrganization
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,9 @@ import {
|
|||||||
ISecret,
|
ISecret,
|
||||||
IServiceAccount,
|
IServiceAccount,
|
||||||
User,
|
User,
|
||||||
Membership
|
Membership,
|
||||||
|
IOrganization,
|
||||||
|
Organization,
|
||||||
} from '../models';
|
} from '../models';
|
||||||
import { sendMail } from './nodemailer';
|
import { sendMail } from './nodemailer';
|
||||||
import { validateMembership } from './membership';
|
import { validateMembership } from './membership';
|
||||||
@@ -288,11 +290,39 @@ const validateUserClientForServiceAccount = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that user (client) can access organization [organization]
|
||||||
|
* @param {Object} obj
|
||||||
|
* @param {User} obj.user - user client
|
||||||
|
* @param {Organization} obj.organization - organization to validate against
|
||||||
|
*/
|
||||||
|
const validateUserClientForOrganization = async ({
|
||||||
|
user,
|
||||||
|
organization,
|
||||||
|
acceptedRoles,
|
||||||
|
acceptedStatuses
|
||||||
|
}: {
|
||||||
|
user: IUser;
|
||||||
|
organization: IOrganization;
|
||||||
|
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
|
||||||
|
acceptedStatuses: Array<'invited' | 'accepted'>;
|
||||||
|
}) => {
|
||||||
|
const membershipOrg = await validateMembershipOrg({
|
||||||
|
userId: user._id,
|
||||||
|
organizationId: organization._id,
|
||||||
|
acceptedRoles,
|
||||||
|
acceptedStatuses
|
||||||
|
});
|
||||||
|
|
||||||
|
return membershipOrg;
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
setupAccount,
|
setupAccount,
|
||||||
completeAccount,
|
completeAccount,
|
||||||
checkUserDevice,
|
checkUserDevice,
|
||||||
validateUserClientForWorkspace,
|
validateUserClientForWorkspace,
|
||||||
validateUserClientForSecrets,
|
validateUserClientForSecrets,
|
||||||
validateUserClientForServiceAccount
|
validateUserClientForServiceAccount,
|
||||||
|
validateUserClientForOrganization
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const requireAuth = ({
|
|||||||
acceptedAuthModes: string[];
|
acceptedAuthModes: string[];
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
|
||||||
// validate auth token against accepted auth modes [acceptedAuthModes]
|
// validate auth token against accepted auth modes [acceptedAuthModes]
|
||||||
// and return token type [authTokenType] and value [authTokenValue]
|
// and return token type [authTokenType] and value [authTokenValue]
|
||||||
const { authMode, authTokenValue } = validateAuthMode({
|
const { authMode, authTokenValue } = validateAuthMode({
|
||||||
@@ -87,7 +88,7 @@ const requireAuth = ({
|
|||||||
|
|
||||||
req.authData = {
|
req.authData = {
|
||||||
authMode,
|
authMode,
|
||||||
authPayload
|
authPayload // User, ServiceAccount, ServiceTokenData
|
||||||
}
|
}
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ const requireMembershipOrgAuth = ({
|
|||||||
acceptedStatuses,
|
acceptedStatuses,
|
||||||
location = 'params'
|
location = 'params'
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
|
||||||
acceptedStatuses: string[];
|
acceptedStatuses: Array<'invited' | 'accepted'>;
|
||||||
location?: req;
|
location?: req;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { Types } from 'mongoose';
|
|||||||
import { IOrganization, MembershipOrg } from '../models';
|
import { IOrganization, MembershipOrg } from '../models';
|
||||||
import { UnauthorizedRequestError, ValidationError } from '../utils/errors';
|
import { UnauthorizedRequestError, ValidationError } from '../utils/errors';
|
||||||
import { validateMembershipOrg } from '../helpers/membershipOrg';
|
import { validateMembershipOrg } from '../helpers/membershipOrg';
|
||||||
|
import { validateClientForOrganization } from '../helpers/organization';
|
||||||
|
|
||||||
type req = 'params' | 'body' | 'query';
|
type req = 'params' | 'body' | 'query';
|
||||||
|
|
||||||
@@ -16,20 +17,31 @@ type req = 'params' | 'body' | 'query';
|
|||||||
const requireOrganizationAuth = ({
|
const requireOrganizationAuth = ({
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses,
|
acceptedStatuses,
|
||||||
location = 'params'
|
locationOrganizationId = 'params'
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
|
||||||
acceptedStatuses: string[];
|
acceptedStatuses: Array<'invited' | 'accepted'>;
|
||||||
location?: req;
|
locationOrganizationId?: req;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
const { organizationId } = req[location];
|
const { organizationId } = req[locationOrganizationId];
|
||||||
req.membershipOrg = await validateMembershipOrg({
|
|
||||||
userId: req.user._id,
|
// TODO: incorporate [acceptedRoles] and [acceptedStatuses]
|
||||||
|
|
||||||
|
const { organization, membershipOrg } = await validateClientForOrganization({
|
||||||
|
authData: req.authData,
|
||||||
organizationId: new Types.ObjectId(organizationId),
|
organizationId: new Types.ObjectId(organizationId),
|
||||||
acceptedRoles,
|
acceptedRoles,
|
||||||
acceptedStatuses
|
acceptedStatuses
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (organization) {
|
||||||
|
req.organization = organization;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (membershipOrg) {
|
||||||
|
req.membershipOrg = membershipOrg;
|
||||||
|
}
|
||||||
|
|
||||||
return next();
|
return next();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ const requireServiceAccountWorkspacePermissionAuth = ({
|
|||||||
acceptedStatuses,
|
acceptedStatuses,
|
||||||
location = 'params'
|
location = 'params'
|
||||||
}: {
|
}: {
|
||||||
acceptedRoles: string[];
|
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
|
||||||
acceptedStatuses: string[];
|
acceptedStatuses: Array<'invited' | 'accepted'>;
|
||||||
location?: req;
|
location?: req;
|
||||||
}) => {
|
}) => {
|
||||||
return async (req: Request, res: Response, next: NextFunction) => {
|
return async (req: Request, res: Response, next: NextFunction) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Schema, model, Types } from 'mongoose';
|
import { Schema, model, Types, Document } from 'mongoose';
|
||||||
import { OWNER, ADMIN, MEMBER, INVITED, ACCEPTED } from '../variables';
|
import { OWNER, ADMIN, MEMBER, INVITED, ACCEPTED } from '../variables';
|
||||||
|
|
||||||
export interface IMembershipOrg {
|
export interface IMembershipOrg extends Document {
|
||||||
_id: Types.ObjectId;
|
_id: Types.ObjectId;
|
||||||
user: Types.ObjectId;
|
user: Types.ObjectId;
|
||||||
inviteEmail: string;
|
inviteEmail: string;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ router.post(
|
|||||||
requireOrganizationAuth({
|
requireOrganizationAuth({
|
||||||
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
acceptedRoles: [OWNER, ADMIN, MEMBER],
|
||||||
acceptedStatuses: [ACCEPTED],
|
acceptedStatuses: [ACCEPTED],
|
||||||
location: 'body'
|
locationOrganizationId: 'body'
|
||||||
}),
|
}),
|
||||||
serviceAccountsController.createServiceAccount
|
serviceAccountsController.createServiceAccount
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,25 +1,51 @@
|
|||||||
---
|
---
|
||||||
title: "Authentication"
|
title: "Authentication"
|
||||||
|
description: "How to authenticate with the Infisical Public API"
|
||||||
---
|
---
|
||||||
|
|
||||||
To authenticate requests with Infisical, you can either use an API Key or [Infisical Token](../../../getting-started/dashboard/token); certain endpoints will accept either one or both.
|
## Essentials
|
||||||
- API Key: This general-purpose authentication token provides user access to most endpoints in this reference.
|
|
||||||
- [Infisical Token](../../../getting-started/dashboard/token): This authentication token (also referred to as the service token) is scoped to a specific project and environment and used for CRUD secret operations.
|
The Public API accepts multiple modes of authentication being via API Key, Service Account credentials, or [Infisical Token](../../../getting-started/dashboard/token).
|
||||||
|
|
||||||
|
- API Key: Provides full access to all endpoints representing the user.
|
||||||
|
- [Service Account](): Provides scoped access to an organization and select projects representing a machine such as a VM or application client.
|
||||||
|
- [Infisical Token](../../../getting-started/dashboard/token): Provides short-lived, scoped CRUD access to the secrets of a specific project and environment.
|
||||||
|
|
||||||
<AccordionGroup>
|
<AccordionGroup>
|
||||||
<Accordion title="API Key">
|
<Accordion title="API Key">
|
||||||
|
The API key mode uses an API key to authenticate with the API.
|
||||||
|
|
||||||
To authenticate requests with Infisical using the API Key, you must include an API key in the `X-API-KEY` header of HTTP requests made to the platform.
|
To authenticate requests with Infisical using the API Key, you must include an API key in the `X-API-KEY` header of HTTP requests made to the platform.
|
||||||
|
|
||||||
You can obtain an API key in User Settings > API Keys
|
You can obtain an API key in User Settings > API Keys
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
</Accordion>
|
||||||
|
<Accordion title="Service Account">
|
||||||
|
The Service Account mode uses an Access Key to authenticate with the API and a Public Key and Private Key to perform any cryptographic operations.
|
||||||
|
|
||||||
|
To authenticate requests with Infisical using the Access Key, you must include it in the `Authorization` header of HTTP requests made to the platform with the value `Bearer <access_key>`.
|
||||||
|
|
||||||
|
You can create a Service Account in Organization Settings > Service Accounts
|
||||||
|
|
||||||
</Accordion>
|
</Accordion>
|
||||||
<Accordion title="Infisical Token">
|
<Accordion title="Infisical Token">
|
||||||
To authenticate requests with Infisical using the Infisical Token, you must include your Infisical Token in the `Authorization` header of HTTP requests made to the platform with the value `Bearer st.<rest_of_your_infisical_token>`.
|
|
||||||
|
The Infisical Token mode uses an Infisical Token to authenticate with the API.
|
||||||
|
|
||||||
|
To authenticate requests with Infisical using the Infisical Token, you must include your Infisical Token in the `Authorization` header of HTTP requests made to the platform with the value `Bearer <infisical_token>`.
|
||||||
|
|
||||||
You can obtain an Infisical Token in Project Settings > Service Tokens.
|
You can obtain an Infisical Token in Project Settings > Service Tokens.
|
||||||
|
|
||||||

|

|
||||||
</Accordion>
|
</Accordion>
|
||||||
</AccordionGroup>
|
</AccordionGroup>
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
Depending on your use case, it may make sense to use one or another authentication mode:
|
||||||
|
|
||||||
|
- API Key (not recommended): Use if you need full access to the Public API without needing to access any secrets endpoints (because API keys can't encrypt/decrypt secrets).
|
||||||
|
- Service Account (recommeded): Use if you need access to multiple projects and environments in an organization; service accounts can generate short-lived access tokens, making them useful for some complex setups.
|
||||||
|
- Service Token (recommeded): Use if you need short-lived, scoped CRUD access to the secrets of a specific project and environment.
|
||||||
@@ -2,11 +2,17 @@
|
|||||||
title: "Introduction"
|
title: "Introduction"
|
||||||
---
|
---
|
||||||
|
|
||||||
Infisical's REST API provides users an alternative way to programmatically access and manage
|
Infisical's Public (REST) API provides users an alternative way to programmatically access and manage
|
||||||
secrets via HTTPS requests. This can be useful for automating tasks, such as
|
secrets via HTTPS requests. This can be useful for automating tasks, such as
|
||||||
rotating credentials, or for integrating secret management into a larger system.
|
rotating credentials, or for integrating secret management into a larger system.
|
||||||
|
|
||||||
With the REST API, users can create, read, update, and delete secrets, as well as manage access control, query audit logs, and more.
|
With the Public API, users can create, read, update, and delete secrets, as well as manage access control, query audit logs, and more.
|
||||||
|
|
||||||
|
<Warning>
|
||||||
|
We highly recommend using one of the available SDKs when working with the Infisical API.
|
||||||
|
|
||||||
|
If you decide to make your own requests using the API reference instead, be prepared for a steeper learning curve and more manual work.
|
||||||
|
</Warning>
|
||||||
|
|
||||||
## Concepts
|
## Concepts
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ To add a member to your organization, scroll down to the "Organization Members"
|
|||||||
projects by default.
|
projects by default.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|
## Service Accounts
|
||||||
|
|
||||||
|
Service accounts represent machine identities such as VMs or application clients that can authenticate with Infisical. They can be provisioned read/write permissions for project(s) and environment(s).
|
||||||
|
|
||||||
|
To add a service account to your organization, scroll down to the "Service Accounts" section and create a service account. Afterwards, you can press on the edit button beside the service account to provision it permissions.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Incident contacts
|
## Incident contacts
|
||||||
|
|
||||||
Incident contacts of an organization are alerted if anything abnormal is detected within the operations of an organization.
|
Incident contacts of an organization are alerted if anything abnormal is detected within the operations of an organization.
|
||||||
|
|||||||
@@ -25,16 +25,16 @@ In most cases, environment variables belong to specific environments: developmen
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Personal/Shared scoping
|
### Personal overrides
|
||||||
|
|
||||||
Every environment variable is classified as either personal or shared.
|
Every environment variable value can be overriden with a custom value.
|
||||||
|
|
||||||
- A personal environment variable is one created by a user of a project to be available for that user only.
|
- An overriden value can only be read and accesssed by the user that overrode the original shared value.
|
||||||
- A shared environment variable is one created by a user of a project to be available for other users of the project.
|
- A (default) shared value can be read and accesssed by other users in a project.
|
||||||
|
|
||||||
You can toggle the classification of an environment variable by pressing on its settings:
|
You can turn overrides on/off by toggling the override/branch icon:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Search
|
### Search
|
||||||
|
|
||||||
@@ -42,12 +42,6 @@ You can search for any environment variable by its key.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
### Sort
|
|
||||||
|
|
||||||
You can sort environment variables alphabetically by their keys.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### Hide/Un-hide
|
### Hide/Un-hide
|
||||||
|
|
||||||
You can hide or un-hide the values of your environment variables. By default, the values are hidden for your privacy.
|
You can hide or un-hide the values of your environment variables. By default, the values are hidden for your privacy.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ These examples demonstrate how to store and fetch environment variables from [In
|
|||||||
|
|
||||||
1. Login or create an account at `app.infisical.com`.
|
1. Login or create an account at `app.infisical.com`.
|
||||||
2. Create a new project.
|
2. Create a new project.
|
||||||
3. Populate your environment variables as in the image below.
|
3. Keep the default environment variables or populate them as in the image below.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 285 KiB After Width: | Height: | Size: 744 KiB |
|
Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 717 KiB |
|
Before Width: | Height: | Size: 244 KiB After Width: | Height: | Size: 622 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 636 KiB |
|
After Width: | Height: | Size: 663 KiB |
|
Before Width: | Height: | Size: 275 KiB After Width: | Height: | Size: 727 KiB |
|
Before Width: | Height: | Size: 271 KiB After Width: | Height: | Size: 669 KiB |
|
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 680 KiB |
|
Before Width: | Height: | Size: 364 KiB After Width: | Height: | Size: 1024 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 668 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 686 KiB |
|
Before Width: | Height: | Size: 262 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 668 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 668 KiB |
|
Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 718 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 668 KiB |
|
Before Width: | Height: | Size: 249 KiB |
|
Before Width: | Height: | Size: 337 KiB After Width: | Height: | Size: 1.0 MiB |