///|
/// Resource limits applied at an application ingress boundary.
pub(all) struct AppPolicy {
max_bytes : Int
max_nodes : Int
max_depth : Int
max_headers : Int
max_batch_messages : Int
max_frame_bytes : Int
} derive(Eq, Debug)
///|
/// Identifies the ingress representation that was accepted.
pub(all) enum AppIngressKind {
IngressDocument
IngressMessage
IngressBatch
IngressFrames
} derive(Eq, Debug)
///|
/// One policy violation suitable for logs or an API response.
pub(all) struct AppPolicyIssue {
path : String
code : String
message : String
} derive(Eq, Debug)
///|
/// A policy report retains every independent limit violation.
pub(all) struct AppPolicyReport {
valid : Bool
issues : Array[AppPolicyIssue]
} derive(Eq, Debug)
///|
/// Result returned by the application ingress helpers.
pub(all) struct AppIngestResult {
accepted : Bool
kind : AppIngressKind
value : CborValue?
values : Array[CborValue]
stats : CborDocumentStats
report : AppPolicyReport
} derive(Debug)
///|
/// A practical default policy for service and edge workloads.
pub fn app_policy_default() -> AppPolicy {
{
max_bytes: 1024 * 1024,
max_nodes: 10000,
max_depth: 64,
max_headers: 64,
max_batch_messages: 1024,
max_frame_bytes: 1024 * 1024,
}
}
///|
/// A smaller policy useful for untrusted public endpoints.
pub fn app_policy_strict() -> AppPolicy {
{
max_bytes: 256 * 1024,
max_nodes: 4096,
max_depth: 32,
max_headers: 32,
max_batch_messages: 256,
max_frame_bytes: 256 * 1024,
}
}
///|
/// Build a policy with explicit limits for deterministic tests and deployments.
pub fn app_policy_with_limits(
base : AppPolicy,
max_bytes : Int,
max_nodes : Int,
max_depth : Int,
max_headers : Int,
max_batch_messages : Int,
max_frame_bytes : Int,
) -> AppPolicy {
{
max_bytes: if max_bytes < 1 {
base.max_bytes
} else {
max_bytes
},
max_nodes: if max_nodes < 1 {
base.max_nodes
} else {
max_nodes
},
max_depth: if max_depth < 1 {
base.max_depth
} else {
max_depth
},
max_headers: if max_headers < 1 {
base.max_headers
} else {
max_headers
},
max_batch_messages: if max_batch_messages < 1 {
base.max_batch_messages
} else {
max_batch_messages
},
max_frame_bytes: if max_frame_bytes < 1 {
base.max_frame_bytes
} else {
max_frame_bytes
},
}
}
///|
/// Return a policy line for startup logs and configuration audits.
pub fn app_policy_summary(policy : AppPolicy) -> String {
"bytes=\{policy.max_bytes} nodes=\{policy.max_nodes} depth=\{policy.max_depth} headers=\{policy.max_headers} batch=\{policy.max_batch_messages} frame=\{policy.max_frame_bytes}"
}
///|
fn policy_issue(
path : String,
code : String,
message : String,
) -> AppPolicyIssue {
{ path, code, message }
}
///|
fn policy_report(issues : Array[AppPolicyIssue]) -> AppPolicyReport {
{ valid: issues.length() == 0, issues }
}
///|
/// Render one policy issue in a stable log-friendly form.
pub fn app_policy_issue_to_string(issue : AppPolicyIssue) -> String {
issue.code + " at " + issue.path + ": " + issue.message
}
///|
/// Render all policy issues in insertion order.
pub fn app_policy_report_to_string(report : AppPolicyReport) -> String {
if report.valid {
"valid"
} else {
let builder = StringBuilder::new()
for i = 0; i < report.issues.length(); i = i + 1 {
if i > 0 {
builder.write_string("\n")
}
builder.write_string(app_policy_issue_to_string(report.issues[i]))
}
builder.to_string()
}
}
///|
/// Combine policy reports from multiple documents.
pub fn app_policy_combine(
first : AppPolicyReport,
second : AppPolicyReport,
) -> AppPolicyReport {
let issues = []
for issue in first.issues {
issues.push(issue)
}
for issue in second.issues {
issues.push(issue)
}
policy_report(issues)
}
///|
/// Prefix issues when a payload is embedded in a larger protocol object.
pub fn app_policy_prefix(
prefix : String,
report : AppPolicyReport,
) -> AppPolicyReport {
let issues = []
for issue in report.issues {
issues.push(policy_issue(prefix + issue.path, issue.code, issue.message))
}
policy_report(issues)
}
///|
/// Check structural resource limits for one CBOR document.
pub fn cbor_policy_check(
value : CborValue,
policy : AppPolicy,
) -> AppPolicyReport {
let issues = []
let stats = cbor_document_stats(value)
if stats.encoded_bytes > policy.max_bytes {
issues.push(
policy_issue(
"$", "max_bytes", "encoded document exceeds the configured byte limit",
),
)
}
if stats.nodes > policy.max_nodes {
issues.push(
policy_issue("$", "max_nodes", "document contains too many nodes"),
)
}
if stats.max_depth > policy.max_depth {
issues.push(
policy_issue(
"$", "max_depth", "document nesting exceeds the configured depth",
),
)
}
policy_report(issues)
}
///|
fn cbor_policy_check_headers(
message : AppMessage,
policy : AppPolicy,
) -> AppPolicyReport {
let issues = []
if message.headers.length() > policy.max_headers {
issues.push(
policy_issue(
"$.headers", "max_headers", "message contains too many headers",
),
)
}
policy_report(issues)
}
///|
fn cbor_policy_check_batch(
batch : AppMessageBatch,
policy : AppPolicy,
) -> AppPolicyReport {
let issues = []
if batch.messages.length() > policy.max_batch_messages {
issues.push(
policy_issue(
"$.messages", "max_batch_messages", "batch contains too many messages",
),
)
}
for i = 0; i < batch.messages.length(); i = i + 1 {
let message_report = cbor_policy_check(batch.messages[i].payload, policy)
for issue in message_report.issues {
issues.push(
policy_issue(
"$.messages[" + i.to_string() + "].payload" + issue.path,
issue.code,
issue.message,
),
)
}
let header_report = cbor_policy_check_headers(batch.messages[i], policy)
for issue in header_report.issues {
issues.push(issue)
}
}
policy_report(issues)
}
///|
fn empty_ingest_result(kind : AppIngressKind) -> AppIngestResult {
{
accepted: false,
kind,
value: None,
values: [],
stats: cbor_document_stats(CborValue::Simple(22)),
report: policy_report([]),
}
}
///|
fn result_for_value(
kind : AppIngressKind,
value : CborValue,
report : AppPolicyReport,
) -> AppIngestResult {
{
accepted: report.valid,
kind,
value: Some(value),
values: [value],
stats: cbor_document_stats(value),
report,
}
}
///|
/// Decode and policy-check a raw CBOR document at an application boundary.
pub fn cbor_ingest_document(
bytes : Bytes,
policy : AppPolicy,
) -> AppIngestResult raise CborError {
if bytes.length() > policy.max_bytes {
let result = empty_ingest_result(IngressDocument)
return {
..result,
report: policy_report([
policy_issue(
"$", "max_bytes", "wire payload exceeds the configured byte limit",
),
]),
}
}
let value = decode(bytes)
result_for_value(IngressDocument, value, cbor_policy_check(value, policy))
}
///|
/// Decode and policy-check one versioned application message.
pub fn cbor_ingest_message(
bytes : Bytes,
policy : AppPolicy,
) -> AppIngestResult raise CborError {
if bytes.length() > policy.max_bytes {
let result = empty_ingest_result(IngressMessage)
return {
..result,
report: policy_report([
policy_issue(
"$", "max_bytes", "message wire payload exceeds the configured byte limit",
),
]),
}
}
let message = decode_app_message(bytes)
let payload_report = cbor_policy_check(message.payload, policy)
let header_report = cbor_policy_check_headers(message, policy)
let report = app_policy_combine(payload_report, header_report)
result_for_value(IngressMessage, app_message_to_cbor(message), report)
}
///|
/// Decode and policy-check one ordered application batch.
pub fn cbor_ingest_batch(
bytes : Bytes,
policy : AppPolicy,
) -> AppIngestResult raise CborError {
if bytes.length() > policy.max_bytes {
let result = empty_ingest_result(IngressBatch)
return {
..result,
report: policy_report([
policy_issue(
"$", "max_bytes", "batch wire payload exceeds the configured byte limit",
),
]),
}
}
let batch = decode_app_batch(bytes)
let report = cbor_policy_check_batch(batch, policy)
let values = []
for message in batch.messages {
values.push(app_message_to_cbor(message))
}
{
accepted: report.valid,
kind: IngressBatch,
value: Some(app_batch_to_cbor(batch)),
values,
stats: cbor_document_stats(app_batch_to_cbor(batch)),
report,
}
}
///|
/// Decode and policy-check every value in a length-delimited frame stream.
pub fn cbor_ingest_frames(
bytes : Bytes,
policy : AppPolicy,
) -> AppIngestResult raise CborError {
if bytes.length() > policy.max_bytes {
let result = empty_ingest_result(IngressFrames)
return {
..result,
report: policy_report([
policy_issue(
"$", "max_bytes", "frame stream exceeds the configured byte limit",
),
]),
}
}
let values = decode_cbor_frames(bytes, policy.max_frame_bytes)
let issues = []
let mut nodes = 0
let mut depth = 0
for i = 0; i < values.length(); i = i + 1 {
let value = values[i]
let report = cbor_policy_check(value, policy)
for issue in report.issues {
issues.push(
policy_issue(
"$.frames[" + i.to_string() + "]." + issue.path,
issue.code,
issue.message,
),
)
}
let stats = cbor_document_stats(value)
nodes = nodes + stats.nodes
if stats.max_depth > depth {
depth = stats.max_depth
}
}
let report = policy_report(issues)
{
accepted: report.valid,
kind: IngressFrames,
value: None,
values,
stats: {
nodes,
containers: 0,
max_depth: depth,
text_bytes: 0,
binary_bytes: 0,
encoded_bytes: bytes.length(),
},
report,
}
}
///|
/// Return true when a raw document passes the configured policy.
pub fn cbor_policy_accepts(value : CborValue, policy : AppPolicy) -> Bool {
cbor_policy_check(value, policy).valid
}
///|
/// Validate a message payload together with its application headers.
pub fn cbor_message_policy_accepts(
message : AppMessage,
policy : AppPolicy,
) -> Bool {
cbor_policy_check(message.payload, policy).valid &&
cbor_policy_check_headers(message, policy).valid
}
///|
/// Return a compact summary of an ingress result for metrics.
pub fn app_ingest_summary(result : AppIngestResult) -> String {
let status = if result.accepted { "accepted" } else { "rejected" }
let kind = match result.kind {
IngressDocument => "document"
IngressMessage => "message"
IngressBatch => "batch"
IngressFrames => "frames"
}
"status=\{status} kind=\{kind} values=\{result.values.length()} nodes=\{result.stats.nodes} bytes=\{result.stats.encoded_bytes} issues=\{result.report.issues.length()}"
}
///|
/// Return all policy issue codes in stable order.
pub fn app_ingest_issue_codes(result : AppIngestResult) -> Array[String] {
let codes = []
for issue in result.report.issues {
codes.push(issue.code)
}
codes
}
///|
/// Reject a report with a caller-provided business rule.
pub fn app_ingest_add_business_issue(
result : AppIngestResult,
path : String,
code : String,
message : String,
) -> AppIngestResult {
let issues = []
for issue in result.report.issues {
issues.push(issue)
}
issues.push(policy_issue(path, code, message))
let report = policy_report(issues)
{ ..result, accepted: false, report }
}
///|
/// Return the configured maximum transport size.
pub fn app_policy_transport_limit(policy : AppPolicy) -> Int {
if policy.max_bytes < policy.max_frame_bytes {
policy.max_bytes
} else {
policy.max_frame_bytes
}
}
///|
/// Return whether a batch can be framed under the policy.
pub fn app_batch_fits_policy(
batch : AppMessageBatch,
policy : AppPolicy,
) -> Bool {
batch.messages.length() <= policy.max_batch_messages &&
app_batch_encoded_size(batch) <= policy.max_bytes &&
app_batch_payloads_within_budget(batch, policy.max_nodes)
}
///|
/// Check every document in an ordered collection and retain indexed paths.
pub fn cbor_policy_check_many(
values : Array[CborValue],
policy : AppPolicy,
) -> AppPolicyReport {
let issues = []
if values.length() > policy.max_batch_messages {
issues.push(
policy_issue(
"$.items", "max_batch_messages", "document collection exceeds the configured item limit",
),
)
}
for i = 0; i < values.length(); i = i + 1 {
let report = cbor_policy_check(values[i], policy)
for issue in report.issues {
issues.push(
policy_issue(
"$.items[" + i.to_string() + "]" + issue.path,
issue.code,
issue.message,
),
)
}
}
policy_report(issues)
}
///|
/// Count nodes across a collection for admission control and metrics.
pub fn cbor_policy_many_nodes(values : Array[CborValue]) -> Int {
let mut total = 0
for value in values {
total = total + cbor_document_stats(value).nodes
}
total
}
///|
/// Measure the exact encoded footprint of a collection.
pub fn cbor_policy_many_encoded_bytes(values : Array[CborValue]) -> Int {
let mut total = 0
for value in values {
total = total + encode(value).length()
}
total
}
///|
/// Validate that a policy is internally coherent before accepting config.
pub fn app_policy_is_sane(policy : AppPolicy) -> Bool {
policy.max_bytes > 0 &&
policy.max_nodes > 0 &&
policy.max_depth > 0 &&
policy.max_headers > 0 &&
policy.max_batch_messages > 0 &&
policy.max_frame_bytes > 0 &&
policy.max_frame_bytes <= policy.max_bytes
}
///|
/// Check aggregate byte and node budgets without losing per-document errors.
pub fn app_policy_many_within_budget(
values : Array[CborValue],
policy : AppPolicy,
) -> Bool {
app_policy_is_sane(policy) &&
values.length() <= policy.max_batch_messages &&
cbor_policy_many_encoded_bytes(values) <= policy.max_bytes &&
cbor_policy_many_nodes(values) <= policy.max_nodes &&
cbor_policy_check_many(values, policy).valid
}
///|
/// Return the aggregate node count recorded in an ingress result.
pub fn app_ingest_values_nodes(result : AppIngestResult) -> Int {
cbor_policy_many_nodes(result.values)
}
///|
/// Return the exact re-encoded size of values retained by an ingress result.
pub fn app_ingest_values_encoded_bytes(result : AppIngestResult) -> Int {
cbor_policy_many_encoded_bytes(result.values)
}
///|
/// A single status predicate for adapters that should reject invalid ingress.
pub fn app_ingest_is_valid(result : AppIngestResult) -> Bool {
result.accepted && result.report.valid
}
///|
/// Check whether a policy has no looser resource limit than another policy.
pub fn app_policy_is_stricter_or_equal(
policy : AppPolicy,
other : AppPolicy,
) -> Bool {
policy.max_bytes <= other.max_bytes &&
policy.max_nodes <= other.max_nodes &&
policy.max_depth <= other.max_depth &&
policy.max_headers <= other.max_headers &&
policy.max_batch_messages <= other.max_batch_messages &&
policy.max_frame_bytes <= other.max_frame_bytes
}
///|
/// Produce a compact budget snapshot for logs and telemetry.
pub fn app_policy_budget_summary(
values : Array[CborValue],
policy : AppPolicy,
) -> String {
let bytes = cbor_policy_many_encoded_bytes(values)
let nodes = cbor_policy_many_nodes(values)
"items=\{values.length()} bytes=\{bytes}/\{policy.max_bytes} nodes=\{nodes}/\{policy.max_nodes} valid=\{app_policy_many_within_budget(values, policy)}"
}
///|
/// Count occurrences of a policy code for dashboards and alert grouping.
pub fn app_policy_report_code_count(
report : AppPolicyReport,
code : String,
) -> Int {
let mut count = 0
for issue in report.issues {
if issue.code == code {
count = count + 1
}
}
count
}
///|
/// Test whether a report contains a particular admission failure class.
pub fn app_policy_report_has_code(
report : AppPolicyReport,
code : String,
) -> Bool {
app_policy_report_code_count(report, code) > 0
}
///|
/// Return the first issue code for a stable caller-facing rejection reason.
pub fn app_ingest_primary_issue(result : AppIngestResult) -> String? {
if result.report.issues.length() == 0 {
None
} else {
Some(result.report.issues[0].code)
}
}
///|
/// Check the encoded collection against both storage and transport budgets.
pub fn app_policy_collection_fits_transport(
values : Array[CborValue],
policy : AppPolicy,
) -> Bool {
app_policy_many_within_budget(values, policy) &&
cbor_policy_many_encoded_bytes(values) <= app_policy_transport_limit(policy)
}