Fridai infrastructure resource tagging standard
- Status: Fridai-wide engineering policy
- Effective: 2026-08-03
- Owner: Fridai Engineering
- Review cadence: annually and whenever a provider, ownership model, or infrastructure-management boundary changes
- Nature: mandatory engineering policy, not corporate policy
Purpose
This policy defines the metadata that Fridai attaches to infrastructure resources. Its purpose is to make ownership, purpose, lifecycle, sensitivity, cost, and management authority discoverable without relying on a cloud console, one person’s memory, or a provider-specific naming convention.
The policy applies to cloud, SaaS, on-premises, network, compute, storage, identity, security, DNS, observability, data, messaging, CI/CD, and other infrastructure resources. It applies whether a resource is managed by Terraform, OpenTofu, a deployment tool such as Wrangler, an application pipeline, an external platform, or a temporary manual exception.
Tags supplement the canonical identifier and registry. They do not replace resource names, Git history, state ownership, access controls, data classification controls, or the Fridai technology registry.
Normative language
- MUST is required for ownership, security, lifecycle, or operational safety.
- SHOULD is the normal rule; deviations require a recorded reason.
- MAY is optional.
Required metadata
Fridai-owned infrastructure MUST have the following metadata. When the provider supports native tags or labels, use the exact key. When it does not, record the same fields in the infrastructure inventory and use the fallback hierarchy below.
| Key | Meaning | Allowed form |
|---|---|---|
fridai.canonical-id | Registered product, service, or platform identity | Fridai canonical ID, for example fio-redline |
fridai.owner | Accountable team or operational function | Registered team slug; never a person’s name or email address |
fridai.scope | Resource ownership boundary | org, shared, product, service, or project |
fridai.environment | Deployment environment | prod, stg, test, dev, or shared |
fridai.lifecycle | Current lifecycle state | experiment, rc, active, deprecated, retiring, or retired |
fridai.managed-by | System authorized to mutate the resource | terraform, opentofu, wrangler, pipeline, manual, or external |
fridai.repository | Repository responsible for the resource | Canonical GitLab project path, without credentials or query parameters |
fridai.data-classification | Highest data classification permitted | public, internal, confidential, or restricted |
fridai.criticality | Operational recovery priority | tier-0, tier-1, tier-2, or tier-3 |
Additional conditional tags are:
| Key | Required when | Allowed form |
|---|---|---|
fridai.state | Terraform or OpenTofu owns the resource | Exact remote state name |
fridai.expires-on | Resource is ephemeral, experimental, or approved as temporary | ISO 8601 calendar date: YYYY-MM-DD |
fridai.cost-center | Cost allocation is configured for the provider or service | Registered finance identifier |
fridai.component | One canonical capability has independently operated components | Registered component suffix |
Criticality has the following meaning:
tier-0: loss compromises identity, control-plane access, security, or recovery of multiple production systems;tier-1: loss stops a production product or a material business process;tier-2: loss degrades a production capability but has a practical workaround;tier-3: development, experiment, convenience, or non-critical support infrastructure.
Criticality is not a claim about data sensitivity. Both fields are required.
Syntax and value rules
- Fridai-owned keys MUST use the
fridai.namespace. Provider limitations may require a documented equivalent, but abbreviating keys for convenience is not permitted. - Keys and controlled values use lowercase kebab case, except that keys retain the periods shown above and dates use ISO format.
- Values MUST be stable identifiers, not presentation labels.
- Tags MUST NOT contain credentials, tokens, personal data, private URLs, incident details, commit hashes, mutable software versions, or unregistered abbreviations.
- Environment, lifecycle, and ownership values MUST come from the controlled values in this policy. New values require a policy update.
- A resource may carry provider or third-party tags outside the
fridai.namespace. Fridai automation MUST preserve tags it does not own. - The provider’s stricter length and character limits always apply.
Management hierarchy
Use the first supported mechanism in this order:
- Declare native tags or labels in the same Terraform/OpenTofu resource that owns the infrastructure object.
- If the provider exposes tags through a separate first-class resource, declare that resource in the same state and preserve single ownership.
- If the provider API supports tags but its Terraform provider does not, store a declarative tag manifest beside the owning root and reconcile it through a dedicated, idempotent API client.
- If the resource cannot be tagged, record all required fields in the version-controlled inventory and, where safe, add a human-readable provider description.
Lack of provider tag support is not an exception to the metadata requirement. It changes the storage mechanism, not the required information.
Provisioners, local-exec, and one-off shell commands MUST NOT be used to hide
tag mutations inside a Terraform apply. An API reconciler is a separately tested
and observable step with read-only drift detection and an explicit write phase.
Ownership and writer rules
- Exactly one management system owns a resource and its Fridai tags.
fridai.managed-byMUST agree with the source that is authorized to mutate the resource.- Terraform, Wrangler, application pipelines, and manual operators MUST NOT concurrently manage the same resource or the same Fridai tag set.
- Importing a resource does not establish ownership by itself. Ownership changes only after the inventory, state boundary, import, and first reviewed no-op plan are complete.
- A manual emergency change MUST be reconciled back into the declared source or recorded as an exception before normal changes resume.
- Tags on resources classified
observe-only,retiring, orunknown-ownerMUST NOT be mutated merely to make them compliant. Their metadata remains in inventory until ownership and mutation authority are established.
Cloudflare implementation
Cloudflare Resource Tagging is currently a public-beta, account-level feature available on all plans. It supports many, but not all, Cloudflare resource types. Fridai therefore treats Cloudflare tags as useful discovery metadata, not as the only inventory or authorization control.
For Cloudflare resources:
- Use an Account Owned Token with the least privileges required by the tagging and inventory APIs. Do not use a Global API Key.
- Retrieve current tags, merge Fridai-owned changes, and replace the set using
the API’s
PUToperation. Cloudflare does not provide a tagPATCHoperation. - Use
ETagandIf-Matchwhen available to prevent lost concurrent updates. - Preserve tags outside the
fridai.namespace. - Do not use the delete-all-tags operation as an update shortcut.
- Treat the documented error for a resource that has never been tagged as an empty current set only when the resource identity has already been verified.
- Paginate inventory and reconciliation calls; Cloudflare currently fixes tag pagination at 100 results.
- Respect Cloudflare’s account tag limit and current syntax limits. Fridai keys use periods because Cloudflare accepts letters, numbers, underscore, period, and hyphen but not colon.
- Prefer a native Cloudflare provider resource only after the pinned provider schema proves that the resource and tag behavior exist. Until then, use the manifest and reconciler pattern; do not invent HCL resource names.
- The merge-request pipeline performs read-only tag drift detection. A protected, blocking manual job may reconcile tags only after the corresponding infrastructure apply is approved.
Example manifest entry:
resource:
type: cloudflare_zero_trust_tunnel_cloudflared
account_id: ${CLOUDFLARE_ACCOUNT_ID}
id: ${TUNNEL_ID}
tags:
fridai.canonical-id: fio-redline
fridai.owner: platform-engineering
fridai.scope: service
fridai.environment: prod
fridai.lifecycle: rc
fridai.managed-by: terraform
fridai.repository: fridai/fio-infra/fio-org-iac-cf
fridai.state: cloudflare-fio-redline-prod
fridai.data-classification: confidential
fridai.criticality: tier-1
Identifiers are resolved at runtime from approved inventory or Terraform outputs. Secrets and raw API responses are never written to the manifest.
Terraform implementation
Terraform and OpenTofu roots SHOULD define their common metadata once and merge resource-specific additions without allowing required keys to be silently overridden:
locals {
required_tags = {
"fridai.canonical-id" = "fio-redline"
"fridai.owner" = "platform-engineering"
"fridai.scope" = "service"
"fridai.environment" = "prod"
"fridai.lifecycle" = "rc"
"fridai.managed-by" = "terraform"
"fridai.repository" = "fridai/fio-infra/fio-org-iac-cf"
"fridai.state" = "cloudflare-fio-redline-prod"
"fridai.data-classification" = "confidential"
"fridai.criticality" = "tier-1"
}
}
Do not add a tags argument to a resource unless the pinned provider schema
supports it.
CI enforcement
Infrastructure repositories MUST:
- validate required metadata and controlled values on merge requests;
- fail when two manifests claim the same resource or a resource has two proposed management owners;
- report missing or drifted tags without exposing sensitive provider payloads;
- block write reconciliation outside the protected default branch;
- retain evidence of the reconciled resource ID, tag-set digest, pipeline, actor, and timestamp without retaining credentials;
- run scheduled read-only drift checks; and
- create or update a tracked issue when drift cannot be reconciled safely.
Exceptions
An exception requires:
- affected resource IDs;
- accountable owner;
- reason the normal mechanism cannot be used;
- compensating inventory control;
- security and lifecycle impact;
- expiry or review date; and
- link to the approving GitLab issue or merge request.
Permanent undocumented exceptions are not permitted.