Self-hosting
Create the Microsoft Entra ID application secret for AWS
This guide is for the customer administrator preparing the AWS Secrets Manager secret for a Markyard hosting whose selected identity provider is Microsoft Entra ID.
Do not use this page for an Auth0 hosting. Complete the Microsoft Entra ID application setup first.
Before you begin
You need:
- the deployment AWS account and Region;
- permission to create a Secrets Manager secret there;
- the Entra Directory (tenant) ID, Application (client) ID, and client secret Value from the Markyard Web app registration; and
- a stable Markyard organization identifier such as
org_acme.
The organization identifier is a Markyard data boundary, not the Entra tenant ID. Choose it once and never change it after users or documents exist.
1. Generate the encryption keys
On a trusted administrative workstation, generate 64 random bytes encoded as unpadded base64url:
openssl rand -base64 64 | tr '+/' '-_' | tr -d '=\n'
Generate a separate 32-byte key for provider-token encryption:
openssl rand -base64 32 | tr '+/' '-_' | tr -d '=\n'
Copy both results directly into the secret document. Do not put them in a ticket, chat, source-control repository, or shared command history.
2. Build the secret document
Create the following JSON document in a secure temporary editor and replace every uppercase placeholder:
{
"authCookieKey": "GENERATED_COOKIE_KEY",
"providerTokenKeysJson": "{\"active\":\"v1\",\"keys\":{\"v1\":\"GENERATED_PROVIDER_TOKEN_KEY\"}}",
"oidcProvidersJson": "[{\"id\":\"entra\",\"display_name\":\"Microsoft Entra ID\",\"organization_id\":\"org_CUSTOMER\",\"issuer_url\":\"https://login.microsoftonline.com/ENTRA_TENANT_ID/v2.0\",\"client_id\":\"ENTRA_APPLICATION_CLIENT_ID\",\"client_secret\":\"ENTRA_CLIENT_SECRET_VALUE\",\"scopes\":[\"openid\",\"profile\",\"email\",\"offline_access\",\"User.ReadBasic.All\"],\"require_email_verified\":false,\"directory\":{\"kind\":\"entra\",\"excluded_account_suffixes\":[\"-Admin\",\" Admin\"]}}]"
}
Important details:
oidcProvidersJsonis a string containing a JSON array, so its inner quotation marks remain escaped.- The array contains exactly one provider.
- Keep
idasentra; the deployment configuration must use the same provider ID. - Put the tenant GUID in the issuer URL. Do not use
common,organizations, orconsumers. - Supply the client secret Value, not its Secret ID.
- Keep
require_email_verifieddisabled because Entra ID does not reliably provide the standard OIDCemail_verifiedclaim. - Do not add extra top-level keys.
Validate the JSON locally with a security-approved JSON tool without sending it to an online formatter.
Entra directory search
Markyard searches users on behalf of the signed-in user. On the existing Markyard Web app
registration, add Microsoft Graph Delegated User.ReadBasic.All. Markyard also supports
delegated User.Read.All for tenants that have already consented that broader permission;
move to User.ReadBasic.All when practical. Markyard requests offline_access so it can
refresh the delegated Graph access token.
The same permission covers profile pictures, which Markyard reads with the signed-in user's own delegated token. Accounts without a picture fall back to that person's initials. No extra permission or consent step is needed.
Microsoft recommends granting the least-privileged permissions an application needs. Review the current descriptions and consent requirements in the Microsoft Graph permissions reference.
The provider configuration enables this behavior and can hide administrative accounts from sharing:
{
"kind": "entra",
"excluded_account_suffixes": ["-Admin", " Admin"]
}
excluded_account_suffixes is optional. Markyard compares each configured suffix
case-insensitively with the Entra display name and with the local part of the mail and
user-principal-name fields. Matching accounts are omitted from people search and cannot be
resolved for a new share. The setting does not revoke access that was granted previously.
Markyard does not request group permissions and does not expose Entra group sharing. Provider access and refresh tokens remain encrypted on the server and are never sent to the browser.
3. Store the secret in AWS
In the deployment account and Region:
- Open AWS Secrets Manager and select Store a new secret.
- Select Other type of secret.
- Open Plaintext and paste the complete outer JSON object.
- Use the AWS managed Secrets Manager key, or select the customer-managed KMS key named in your deployment design.
- Name the secret for the installation, for example
markyard/production/application. - Do not configure automatic rotation for this compound secret. Coordinate application credential rotation with a deployment and sign-in check.
- Store the secret and copy its complete ARN, including AWS's six-character suffix.
AWS cautions that secret values placed directly in shell commands can be recovered from shell history or process inspection. The console or a security-approved file-based AWS CLI workflow avoids putting the value on the command line. See Create an AWS Secrets Manager secret.
Delete the temporary plaintext document securely after confirming that the secret is stored and recoverable by authorized operators.
4. Complete the deployment configuration
Set the deployment configuration values to:
{
"auth": {
"providerId": "entra",
"applicationSecretArn": "COMPLETE_SECRET_ARN"
}
}
When the secret uses a customer-managed KMS key, also add its complete key ARN as
applicationSecretKmsKeyArn.
Return to Deploy Markyard in your AWS account to validate, review, and deploy the stacks.
Rotate credentials
For an Entra client-secret rotation:
- Create a replacement secret before the current secret expires and copy its Value.
- Update only the relevant client-secret value inside
oidcProvidersJson; preserve the cookie key, provider ID, issuer, tenant, and organization identifier. - Save a new Secrets Manager secret version.
- Run the deployment diff and deployment so ECS starts a new task definition referencing the current secret.
- Verify browser sign-in and people search.
- Delete the superseded Entra secret after validation.
Troubleshooting
- Provider mismatch: the provider object and deployment configuration must both use
entra. - OIDC discovery failure: verify the tenant GUID and
/v2.0issuer URL. - Invalid client secret: confirm that the stored value is the secret Value, not its Secret ID, and that it has not expired.
- Directory
401or403: confirm delegatedUser.ReadBasic.All(preferred) orUser.Read.All, organizational consent, the configured scopes, tenant ID, and client ID; then reconnect the signed-in user. - Initials where a profile picture is expected: confirm the person has a picture set in Microsoft 365 or Entra ID, then check the same delegated permission as directory search — avatars use that token. Profile pictures are unavailable in Azure AD B2C tenants.
- Secret validation failure: confirm the outer object has exactly three keys, the inner provider array contains exactly one object, the cookie key decodes to 64 bytes, and the active provider-token key decodes to 32 bytes.