> For the complete documentation index, see [llms.txt](https://docs.keeper.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keeper.io/keeperpam/privileged-access-manager/universal-secrets-sync/advanced.md).

# Advanced

Technical details of Universal Secrets Sync

This page outlines some of the more advanced behavior of USS across AWS, Azure, and Google Cloud. If you are migrating existing cloud secrets into Keeper first, see the [Migration Guide](/keeperpam/privileged-access-manager/universal-secrets-sync/migration.md). You may also want to review the [basics](/keeperpam/privileged-access-manager/universal-secrets-sync/setup.md).

### Secret Name Format: Record Title <a href="#secret-naming-rules" id="secret-naming-rules"></a>

Cloud secret names are based on Keeper record titles and are validated and converted according to each provider's naming requirements. If a record's title is change then a new secret will be created with the corresponding name.

### Secret Naming Rules <a href="#secret-naming-rules" id="secret-naming-rules"></a>

#### AWS Secrets Manager <a href="#aws-secrets-manager-1" id="aws-secrets-manager-1"></a>

* **Length**: 1-512 characters
* **Allowed**: Alphanumeric + `/_+=.@-`
* **Conversion**: Spaces → hyphens
* **Example**: "My Secret" → "My-Secret"

#### Azure Key Vault <a href="#azure-key-vault-1" id="azure-key-vault-1"></a>

* **Length**: 1-127 characters
* **Allowed**: Alphanumeric + hyphens
* **Must start**: With a letter
* **Must end**: With letter or digit
* **Conversion**: Spaces → hyphens
* **Example**: "My Secret" → "My-Secret"

#### GCP Secret Manager <a href="#gcp-secret-manager" id="gcp-secret-manager"></a>

* **Length**: 1-255 characters
* **Allowed**: Alphanumeric + hyphens + underscores
* **Must start**: With a letter
* **Must end**: With letter, digit, or underscore
* **Conversion**: Spaces → hyphens
* **Example**: "My Secret" → "My-Secret"

#### GitHub Actions <a href="#gcp-secret-manager" id="gcp-secret-manager"></a>

* **Length**: 1-256 characters
* **Allowed**: uppercase letters (`A–Z`), digits (`0–9`), and underscores (`_`).
* **Must start**: With a letter
* **Cannot start:** With `GITHUB_` (reserved prefix).
* **Conversion**: Spaces → hyphens
* **Example**: "My Secret" → "MY\_SECRET"

#### HashiCorp Vault <a href="#gcp-secret-manager" id="gcp-secret-manager"></a>

* **Length**: 1-512 characters (a conservative ceiling, not a Vault-imposed rule)
* **Allowed**: Alphanumeric + hyphens, underscores, and periods (`^[A-Za-z0-9][A-Za-z0-9_.-]*$`); case is preserved
* **Must start**: With a letter or digit
* **Cannot start:** A name that sanitizes to exactly `.` or `..` is rejected
* **Conversion**: Spaces → hyphens
* **Example**: My Secret" → "My-Secret"

***

### Secret Value Format <a href="#secret-value-format" id="secret-value-format"></a>

#### JSON format (default) <a href="#json-format-default" id="json-format-default"></a>

By default, a synced secret's value is a flat JSON document where each key is derived from the Keeper record's field label (falling back to field type).

Example — a `login` record synced to AWS:

```json
{"login":"admin","password":"s3cr3t","url":"https://example.com"}
```

#### Plain-text format <a href="#plain-text-format" id="plain-text-format"></a>

When a Keeper record's flattened field set contains **exactly one field named `value`**, the gateway skips JSON serialization and stores the raw field value as a plain string. The cloud secret's ContentType (or equivalent label) is set to `text/plain` instead of `application/json`.

This applies to all three providers automatically — no extra configuration is required.

Here are some examples on how records serialized as plain-text secrets look in Keeper Vault:\
\
![](https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2Fr8XCF7An13dXUySXxOEg%2FScreenshot%202026-07-08%20at%201.50.33%E2%80%AFPM.png?alt=media\&token=8c946c61-d485-4aed-a908-cef76ce51929) ![](https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FgrfAmbvzkEoI2Jr8aahi%2FScreenshot%202026-07-08%20at%201.52.22%E2%80%AFPM.png?alt=media\&token=27b121b3-be6f-459b-b69a-89b948c74b90)

Users can update this secret's value in the Vault UI above and the new value will get synced to the cloud as a plain-text secret, as long as the label isn't modified and additional fields aren't added.

**Example**: a record with a single `value: "my-api-key"` field is stored as:

```
my-api-key
```

rather than:

```json
{"value":"my-api-key"}
```

| Condition                                                      | Stored value                   | ContentType        |
| -------------------------------------------------------------- | ------------------------------ | ------------------ |
| Record has 2+ fields, or the single field is not named `value` | Flat JSON document             | `application/json` |
| Record has exactly one field named `value`                     | Raw field value (plain string) | `text/plain`       |

***

### Metadata and Tags <a href="#metadata-and-tags" id="metadata-and-tags"></a>

Every synced secret is tagged with metadata that identifies its origin and record details. Tags are applied when the secret is first created **and** refreshed on every subsequent sync run (update), so the tags always reflect the current state of the Keeper record.

#### Tag / label reference <a href="#tag--label-reference" id="tag--label-reference"></a>

<table><thead><tr><th width="121.07421875">Purpose</th><th>AWS tag key</th><th>Azure tag key</th><th>GCP label key</th></tr></thead><tbody><tr><td>Content Type</td><td><code>ContentType</code></td><td><em>(content_type field)</em></td><td><code>content_type</code></td></tr><tr><td>Origin</td><td><code>Source</code></td><td><code>Source</code></td><td><code>source</code></td></tr><tr><td>Keeper Record Title</td><td><code>keeper_RecordTitle</code></td><td><code>keeper_RecordTitle</code></td><td><code>keeper_recordtitle</code></td></tr><tr><td>Keeper Record Type</td><td><code>keeper_RecordType</code></td><td><code>keeper_RecordType</code></td><td><code>keeper_recordtype</code></td></tr><tr><td>Keeper Record UID</td><td><code>keeper_RecordUID</code></td><td><code>keeper_RecordUID</code></td><td><code>keeper_recorduid</code></td></tr></tbody></table>

**ContentType values**:

| Secret format                     | AWS / Azure value  | GCP label value    |
| --------------------------------- | ------------------ | ------------------ |
| JSON (default)                    | `application/json` | `application_json` |
| Plain text (single `value` field) | `text/plain`       | `text_plain`       |

> **GCP note**: GCP label keys and values must be lowercase. The `keeper_recordtitle` value is sanitized to lowercase with hyphens (e.g. "My Secret" → `my-secret`). The `keeper_recordtype` value is lowercased similarly (e.g. `login`, `custom_myorgtype`). The `keeper_recorduid` value is sanitized the same way. ContentType values follow the same rule: `application/json` → `application_json`, `text/plain` → `text_plain`.

**`keeper_RecordType` values**

Built-in Keeper record types (e.g. `login`, `bankAccount`, `pamMachine`, `pamAwsConfiguration`) are stored verbatim. User-defined custom record types are prefixed with `custom_` so consumers can distinguish them:

| Record type          | Tag value          |
| -------------------- | ------------------ |
| `login`              | `login`            |
| `pamUser`            | `pamUser`          |
| `myOrgType` (custom) | `custom_myOrgType` |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.keeper.io/keeperpam/privileged-access-manager/universal-secrets-sync/advanced.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
