---
id: "credentials-without-rotation"
type: "rule"
severity: "warning"
url: "https://localhost:3000/catalogue/rules/credentials-without-rotation"
---

# Credentials without rotation

The design holds data but declares no credential rotation period and has no key-management node.

| | |
|---|---|
| Severity | warning |
| Selects | every design |
| Components in scope | 2,366 |

## Why

The design stores data but says nothing about rotating the credentials that reach it, and it has no key-management node that would rotate them. A leaked credential stays valid forever.

## What it checks

It looks at every design, and fires when:

- all of these hold:
  - the design contains a node in category data
  - the design requirement `security.credentialRotationDays` has no value
  - this does not hold:
    - the design contains a node of kind key-management

Message template:

```
Design '{{design.id}}' holds data but declares no credential rotation period and has no key-management node.
```

## Applies to

This rule is about the whole design, not one node.

2,366 catalogue components fall under it.

## Tripped by

Reference designs whose broken twin names this rule in its header:

- [ad-click-aggregation](https://localhost:3000/d/zeema/ad-click-aggregation)
- [airbnb-search](https://localhost:3000/d/zeema/airbnb-search)
- [booking-search](https://localhost:3000/d/zeema/booking-search)
- [coinbase-exchange](https://localhost:3000/d/zeema/coinbase-exchange)
- [distributed-message-queue](https://localhost:3000/d/zeema/distributed-message-queue)
- [linkedin-kafka](https://localhost:3000/d/zeema/linkedin-kafka)
- [notion-sharding](https://localhost:3000/d/zeema/notion-sharding)
- [payment-system](https://localhost:3000/d/zeema/payment-system)
- [paypal-payments](https://localhost:3000/d/zeema/paypal-payments)
- [spotify-playback](https://localhost:3000/d/zeema/spotify-playback)
- [whatsapp-messaging](https://localhost:3000/d/zeema/whatsapp-messaging)
- [zoom-video](https://localhost:3000/d/zeema/zoom-video)

## Source (`rule` YAML, verbatim)

```yaml
# yaml-language-server: $schema=../schema/rule.schema.json
# The design stores data but says nothing about rotating the credentials that reach it,
# and there is no key-management node that would rotate them. Leaked credentials then
# stay valid forever.
# Tripped by: designs/payment-system.broken.yaml
schemaVersion: "1"
type: "rule"
id: "credentials-without-rotation"
severity: "warning"
select:
  design: true
when:
  all:
    - hasNode:
        category: "data"
    - requirement: "security.credentialRotationDays"
      exists: false
    - not:
        hasNode:
          kind: "key-management"
message: "Design '{{design.id}}' holds data but declares no credential rotation period and has no key-management node."
```

Human page: https://localhost:3000/catalogue/rules/credentials-without-rotation
