140 lines
4.6 KiB
Markdown
140 lines
4.6 KiB
Markdown
# Application secret grants
|
|
|
|
Maidn stores secret values in OpenBao. Git contains only references and access
|
|
policy. A repository does not get OpenBao access: one named workload identity
|
|
gets one reviewed grant.
|
|
|
|
## Grant classes
|
|
|
|
| Consumer | OpenBao path | Kubernetes namespace | Intended use |
|
|
| --- | --- | --- | --- |
|
|
| `build` | `apps/<app>/build/*` | `tekton-pipelines` | Read-only dependency credentials |
|
|
| `publish` | `apps/<app>/publish/*` | `tekton-pipelines` | One app's artifact repository credential |
|
|
| `runtime` | `apps/<app>/runtime/<environment>/*` | `<app>-<environment>` | Service runtime credentials |
|
|
| shared | `shared/<name>/*` | Granted consumer only | Deliberately shared broker, database, or API credentials |
|
|
|
|
`build` code is repository-controlled. Anything granted to it is readable by a
|
|
pull request author. Do not grant deployment, production, Git write, or
|
|
administrator credentials to a build.
|
|
|
|
## Bootstrap configuration
|
|
|
|
Declare access in the private bootstrap configuration. This declaration has no
|
|
secret values and is reviewed with the platform configuration:
|
|
|
|
```yaml
|
|
secretGrants:
|
|
- application: orders-api
|
|
consumer: publish
|
|
shared:
|
|
- internal-npm
|
|
- application: orders-api
|
|
consumer: runtime
|
|
environment: staging
|
|
shared:
|
|
- rabbitmq
|
|
- application: orders-api
|
|
consumer: runtime
|
|
environment: production
|
|
shared:
|
|
- rabbitmq
|
|
```
|
|
|
|
MaidnCLI validates application, consumer, environment, and shared-grant names.
|
|
It creates one OpenBao policy and Kubernetes-auth role for every declaration.
|
|
The role names are deterministic:
|
|
|
|
```text
|
|
maidn-<app>-build
|
|
maidn-<app>-publish
|
|
maidn-<app>-runtime-<environment>
|
|
```
|
|
|
|
The policy permits only the consumer's own path and the exact `shared/<name>`
|
|
paths listed in its declaration. A shared value is stored once, for example at
|
|
`shared/rabbitmq`, and each service requiring it declares that same shared
|
|
grant. Do not copy it into application paths.
|
|
|
|
## GitOps resources
|
|
|
|
The application environment manifests create the matching ServiceAccount,
|
|
SecretStore, and ExternalSecret. These resources are reviewed GitOps content;
|
|
never create them with `kubectl apply`.
|
|
|
|
For `orders-api` staging, use the matching identity and namespace:
|
|
|
|
```yaml
|
|
apiVersion: v1
|
|
kind: ServiceAccount
|
|
metadata:
|
|
name: maidn-orders-api-runtime-staging
|
|
namespace: orders-api-staging
|
|
---
|
|
apiVersion: external-secrets.io/v1
|
|
kind: SecretStore
|
|
metadata:
|
|
name: openbao-orders-api-staging
|
|
namespace: orders-api-staging
|
|
spec:
|
|
provider:
|
|
vault:
|
|
server: http://openbao.openbao.svc:8200
|
|
path: secret
|
|
version: v2
|
|
auth:
|
|
kubernetes:
|
|
mountPath: kubernetes
|
|
role: maidn-orders-api-runtime-staging
|
|
serviceAccountRef:
|
|
name: maidn-orders-api-runtime-staging
|
|
---
|
|
apiVersion: external-secrets.io/v1
|
|
kind: ExternalSecret
|
|
metadata:
|
|
name: orders-api-rabbitmq
|
|
namespace: orders-api-staging
|
|
spec:
|
|
refreshInterval: 1h
|
|
secretStoreRef:
|
|
name: openbao-orders-api-staging
|
|
kind: SecretStore
|
|
target:
|
|
name: orders-api-rabbitmq
|
|
creationPolicy: Owner
|
|
data:
|
|
- secretKey: password
|
|
remoteRef:
|
|
key: shared/rabbitmq
|
|
property: password
|
|
```
|
|
|
|
The workload references only `orders-api-rabbitmq` in its own namespace. Each
|
|
application/environment needs a separate namespace; do not put runtime
|
|
secrets in shared `staging` or `production` namespaces.
|
|
|
|
## Artifact repositories
|
|
|
|
Create one credential per application and artifact target. Its upstream
|
|
permissions must be limited to the exact package, hosted repository, or object
|
|
prefix. Examples: one npm scope, one Maven hosted repository, one OCI image,
|
|
or S3 `PutObject` for one prefix.
|
|
|
|
Use `publish` for credentials needed to upload a completed artifact. Use
|
|
`build` only for credentials that a build must read, such as a private package
|
|
registry. A custom build upload is an exception: it exposes the token to build
|
|
code and therefore requires a narrowly scoped, disposable credential.
|
|
|
|
## Operations
|
|
|
|
1. Create the least-privilege upstream credential.
|
|
2. Write its value to the declared OpenBao path through a secure stdin-based
|
|
operator workflow. Never put it in YAML, a URL, a command argument, or Git.
|
|
3. Add the reviewed grant and GitOps resources.
|
|
4. Bootstrap or reconcile to create the OpenBao role and policy.
|
|
5. Verify the target ExternalSecret becomes Ready without printing its Secret.
|
|
6. On revocation, remove the grant and ExternalSecret, revoke the upstream
|
|
credential, then restart affected workloads.
|
|
|
|
See [secrets.md](secrets.md) for encrypted operational-material rules and
|
|
[runbooks/credential-rotation.md](runbooks/credential-rotation.md) for rotation.
|