Skip to content

feat(schema): Add approval events#298

Open
xibz wants to merge 2 commits intocdevents:mainfrom
xibz:approval
Open

feat(schema): Add approval events#298
xibz wants to merge 2 commits intocdevents:mainfrom
xibz:approval

Conversation

@xibz
Copy link
Contributor

@xibz xibz commented Feb 27, 2026

Introduces three new event types to model the lifecycle of an approval request in a CI/CD pipeline or workflow.

Many CI/CD systems require a formal decision point before execution can continue, like a deployment to production, a release cut, or a regulated change proceeding through a pipeline. The decision may come from a human approver, an automated policy engine, an external compliance system, or any other entity capable of authorizing progression. There is currently no canonical CDEvents representation for this pattern, leaving teams to model approvals through customData or out of band mechanisms with no shared traversal or governance model.

approval.created: emitted when an approval request is initiated. Captures the requestor and references to the approval details and the resource being gated.

approval.updated: emitted when a non-terminal decision is recorded or when the resource target of the approval changes. Supports flows where multiple decisions may be recorded before a terminal state is reached, whether from humans, automated systems, or a combination.

approval.closed: emitted when the approval reaches a terminal state. Captures the final decision, the responder, and the terminal status: Approved, Rejected, Cancelled, or Expired.

All three events share a common core:

  • approvalDetailsUrl: reference URL to the approval request page
  • resourceTargetUrl: reference URL to the resource being gated

approval.created adds:

  • requestor: the entity that initiated the approval request

approval.updated and approval.closed add:

  • responder: the entity that recorded a decision (URN format)
  • decision: the decision selected by the responder

approval.closed additionally adds:

  • status: example terminal state: approved, rejected, cancelled, expired

  • Deployment gates requiring sign-off before production rollout

  • Automated policy checks that must authorize pipeline progression

  • Regulated change management pipelines requiring auditable approval records

  • Multistage release workflows where approvals gate progression between environments

  • Compliance workflows requiring documented authorization before sensitive operations

  • External system integrations where a thirdparty tool must approve before execution continues

@xibz xibz requested a review from a team as a code owner February 27, 2026 03:01
Introduces three new event types to model the lifecycle of an approval
request in a CI/CD pipeline or workflow.

Many CI/CD systems require a formal decision point before execution can
continue, like a deployment to production, a release cut, or a regulated
change proceeding through a pipeline. The decision may come from a human
approver, an automated policy engine, an external compliance system, or
any other entity capable of authorizing progression. There is currently
no canonical CDEvents representation for this pattern, leaving teams to
model approvals through customData or out of band mechanisms with no
shared traversal or governance model.

**approval.created**: emitted when an approval request is initiated.
Captures the requestor and references to the approval details and the
resource being gated.

**approval.updated**: emitted when a non-terminal decision is recorded
or when the resource target of the approval changes. Supports flows
where multiple decisions may be recorded before a terminal state is
reached, whether from humans, automated systems, or a combination.

**approval.closed**: emitted when the approval reaches a terminal
state.  Captures the final decision, the responder, and the terminal
status: Approved, Rejected, Cancelled, or Expired.

All three events share a common core:
- `approvalDetailsUrl`: reference URL to the approval request page
- `resourceTargetUrl`: reference URL to the resource being gated

approval.created adds:
- `requestor`: the entity that initiated the approval request

approval.updated and approval.closed add:
- `responder`: the entity that recorded a decision (URN format)
- `decision`: the decision selected by the responder

approval.closed additionally adds:
- `status`: example terminal state: approved, rejected, cancelled,
  expired

- Deployment gates requiring sign-off before production rollout
- Automated policy checks that must authorize pipeline progression
- Regulated change management pipelines requiring auditable approval
  records
- Multistage release workflows where approvals gate progression between
  environments
- Compliance workflows requiring documented authorization before
  sensitive operations
- External system integrations where a thirdparty tool must approve
  before execution continues
@sol-duara
Copy link

LGTM

Copy link
Contributor

@davidB davidB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No comments, on the purpose, only on the format (I comment once each "case", not each time the case is present).
Before merging, do not forget to add the json samples as part of the conformance.

"approvalDetailsUrl": {
"type": "string",
"minLength": 1,
"$comment": "Reference URL to the approval request in the originating system. Consumers with appropriate access can retrieve the full approval context, history, and decisions from this URL. This provides the canonical location of the approval record."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, the "$comment" (json draft-07) should be replaced by "description".
https://json-schema.org/understanding-json-schema/reference/metadata

they ($comments) are useful for leaving notes to future editors of a JSON schema, but should not be used to communicate to users of the schema.

from https://json-schema.org/understanding-json-schema/reference/comments

Comment on lines +65 to +66
"approvalDetailsUrl": {
"type": "string",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every xxxUrl should have format uri or uri-reference

            "uri": {
              "type": "string",
              "minLength": 1,
              "format": "uri-reference"
            },

For consistency, I'm also in favor to rename the suffix Uri (IIRC, I open a ticket to rename the renaiming viewUrl & ticketURI.

Comment on lines +59 to +63
"id": {
"type": "string",
"minLength": 1
},
"content": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, we didn't agree on removing subject.source (as I asked).
So it is missing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we agree to make that change in v0.6 we could do that first.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I forgot to include it for only closed.

I think we need consensus on this.

},
"responder": {
"type": "string",
"format": "urn",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find urn format in the json-schema.

Just:

Note also that the "uuid" format is for plain UUIDs, not UUIDs in URNs. An example is "f81d4fae-7dec-11d0-a765-00a0c91e6bf6". For UUIDs as URNs, use the "uri" format, with a "pattern" regular expression of "^urn:uuid:" to indicate the URI scheme and URN namespace.

https://json-schema.org/draft/2020-12/json-schema-validation#name-resource-identifiers

As it's unusual, SDK and implementation, may need some custom adaption.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like urn is covered by uri with pattern matching in json schema

Comment on lines +86 to +91
"enum": [
"Approved",
"Rejected",
"Cancelled",
"Expired"
],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change enum'values to lowercase, like in other schemas.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should update the linter to enforce lower case enum values, then. Is it lower case, camel case, snake case or what?

Signed-off-by: xibz <bjp@apple.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants