Skip to main content

Secret Attributes

The attribute value type Secret stores credentials — passwords, client secrets, API keys, bot tokens, private keys, refresh tokens — encrypted at rest. The engine enforces it: a Secret value is encrypted on every write, no public API returns it, and readers only see whether a value is set.

Availability

The Secret value type is available from System CK model 2.5.0 and the engine release that ships it. Models that use it must depend on System >= 2.5 (see System dependency).

When to Use Secret​

Use Secret for every attribute whose value grants access to something: passwords, client secrets, API keys, tokens, private keys and passphrases, connection strings that contain credentials. Values that identify an account without granting access — user names, client ids, tenant ids — stay String.

A Secret value is used server-side only:

  • the communication controller decrypts secrets when it builds adapter configuration,
  • pipelines read a secret on demand with the RevealSecret@1 node,
  • GraphQL, MCP and octo-cli only report whether a value is set (see Secret Attributes in the API).

Defining a Secret Attribute​

$schema: https://schemas.meshmakers.cloud/construction-kit-elements.schema.json
attributes:
- id: Password
valueType: Secret
description: Password of the mailbox account

Assign it to a type like any other attribute:

types:
- typeId: EMailReceiverConfiguration
derivedFromCkTypeId: System/Configuration
attributes:
- id: ${this}/UserName
name: UserName
- id: ${this}/Password
name: Password
isOptional: true

The value type sits on the attribute definition. If a definition is shared by credential and non-credential attributes, split it first and convert only the credential attribute.

Rules​

The compiler enforces the following rules for a Secret attribute. The numbers refer to the compiler messages below.

RuleMessage
No defaultValues — a credential never ships with the model70
No autoCompleteValues and no autoIncrementReference71
Not an attribute of an association role71
Effective ownership is always Secret. An unset ownership becomes Secret; any other declared ownership is an error72
Not indexable — the stored value is ciphertext73
Not referenced by display rules (displayNameRule, displayDescriptionRule)74
Not referenced by owner attribute paths69
The model depends on System >= 2.575
A record that contains a Secret sub-attribute declares a valid recordKey76, 77

In addition, Secret attributes are never part of query columns, formulas, runtime queries, archive column paths or CrateDB columns.

Ownership Secret means: a blueprint re-apply keeps the stored value, and runtime exports (ExportRt, deep-graph export) never contain it.

Secrets in Records​

A Secret attribute may be a sub-attribute of a record. Because a record array is always written as a whole, the engine must decide per element whether an empty secret means "unchanged". It matches incoming and stored elements by a record key, which the record definition names with recordKey:

$schema: https://schemas.meshmakers.cloud/construction-kit-elements.schema.json
records:
- recordId: ValueOverride
recordKey: Path # names a sub-attribute of the record
attributes:
- id: ${this}/Path
name: Path
- id: ${this}/Value
name: Value # String: non-secret overrides stay readable
- id: ${this}/SecretValue
name: SecretValue # attribute definition with valueType: Secret
- id: ${this}/IsSecret
name: IsSecret

This is the shape of the Helm ValueOverride record in System.Communication 3.41: a secret override sets IsSecret and carries its value in SecretValue; legacy entries that keep an enc:v1 value in Value still deploy but are deprecated.

Rules for recordKey:

  • A record whose own or inherited attributes contain a Secret attribute must have an effective recordKey (own, or inherited from the nearest base record). This applies to the record type, regardless of whether it is used as Record or RecordArray, because another model can reuse it in an array (message 76).
  • The key names a sub-attribute of the record that is required, not Secret and of value type String, Int, Int64 or Enum (message 77).
  • Single Record attributes carry over by position (there is exactly one element); the key is used for RecordArray attributes.

How the carry-over works in the API is described in Secrets in records.

System Dependency​

A model that uses Secret attributes must depend on System >= 2.5, so that an engine that does not know the value type fails with a clear dependency error instead of misreading the attribute:

# ckModel.yaml
dependencies:
- System-[2.5,3.0)

Versioning​

ChangeClassification
valueType changed from String to SecretMINOR
valueType changed from Secret to anything else, or any other valueType changeMAJOR
Record recordKey set, cleared or changedMINOR

String → Secret is Minor because stored values stay readable: readers accept legacy plaintext in a Secret slot until the encryption sweep has run (see Secret Encryption Key Ring). The effective ownership becomes Secret. Clients that select the value as a string must switch to the is-set state before the model change is rolled out. See also Versioning Rules.

Blueprint Seeds​

Blueprint seed data may contain only empty values for Secret attributes; secrets are set after installation. See Secret attributes in seed data.

Compiler Messages​

No.KeyLevelMessage
70SecretAttributeHasDefaultValuesERRORSecret attribute '{ckAttributeId}' declares defaultValues. A Secret attribute cannot have default values - a credential must never ship with the model; set it after installation.
71SecretAttributeAssignmentInvalidERRORSecret attribute '{attributeName}' ('{ckAttributeId}') of '{ckElementId}' is invalid: {reason}
72SecretAttributeOwnershipNotSecretERRORSecret attribute '{attributeName}' of '{ckElementId}' declares ownership '{ownership}'. The effective ownership of a Secret attribute is always 'Secret'; remove the override or declare 'ownership: Secret'.
73SecretAttributeIndexedERRORIndex of type '{ckTypeId}' references Secret attribute path '{attributePath}'. Secret attributes cannot be indexed - the stored value is ciphertext.
74SecretAttributeReferencedByDisplayRuleERRORDisplay rule '{ruleProperty}' of type '{ckTypeId}' references Secret attribute path '{attributePath}'. Display rules cannot reveal Secret attributes.
75SecretAttributeRequiresSystemDependencyERRORConstruction kit model '{modelId}' uses Secret attributes and must depend on System >= {minimumVersion} (declared: {declaredDependency}). Declare the dependency as 'System-[{minimumVersion},3.0)' so engines that do not know the Secret value type fail with a dependency error.
76RecordWithSecretRequiresRecordKeyERRORRecord '{ckRecordId}' contains Secret attribute(s) {secretAttributes} but declares no 'recordKey'. A record with Secret sub-attributes must name the sub-attribute that identifies an element, so a secret left empty on a record array replace can be carried over from the stored element with the same key.
77RecordKeyInvalidERRORRecord key '{recordKey}' of record '{ckRecordId}' is invalid: {reason}

Reasons reported with message 71:

  • Secret attributes cannot be attributes of an association role
  • autoCompleteValues are not allowed - they would publish candidate secrets with the model
  • autoIncrementReference is not allowed - a generated sequence number is not a secret

Reasons reported with message 77:

  • the record has no attribute with this name
  • a Secret attribute cannot be the record key
  • the key attribute must be of value type String, Int, Int64 or Enum
  • the key attribute must not be optional - an element without a key cannot be matched

An owner attribute path that points at a Secret attribute is reported with the existing message 69 (OwnerAttributeInvalid).

See Also​