Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 6 additions & 29 deletions c/src/schema/policy_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,6 @@
#define flatbuffers_extension "bin"
#endif

#define __dd_wls_UUID_formal_args , uint64_t v0, uint64_t v1
#define __dd_wls_UUID_call_args , v0, v1
static inline dd_wls_UUID_t *dd_wls_UUID_assign(dd_wls_UUID_t *p, uint64_t v0, uint64_t v1)
{ p->hi = v0; p->lo = v1;
return p; }
static inline dd_wls_UUID_t *dd_wls_UUID_copy(dd_wls_UUID_t *p, const dd_wls_UUID_t *p2)
{ p->hi = p2->hi; p->lo = p2->lo;
return p; }
static inline dd_wls_UUID_t *dd_wls_UUID_assign_to_pe(dd_wls_UUID_t *p, uint64_t v0, uint64_t v1)
{ flatbuffers_uint64_assign_to_pe(&p->hi, v0); flatbuffers_uint64_assign_to_pe(&p->lo, v1);
return p; }
static inline dd_wls_UUID_t *dd_wls_UUID_copy_to_pe(dd_wls_UUID_t *p, const dd_wls_UUID_t *p2)
{ flatbuffers_uint64_copy_to_pe(&p->hi, &p2->hi); flatbuffers_uint64_copy_to_pe(&p->lo, &p2->lo);
return p; }
static inline dd_wls_UUID_t *dd_wls_UUID_assign_from_pe(dd_wls_UUID_t *p, uint64_t v0, uint64_t v1)
{ flatbuffers_uint64_assign_from_pe(&p->hi, v0); flatbuffers_uint64_assign_from_pe(&p->lo, v1);
return p; }
static inline dd_wls_UUID_t *dd_wls_UUID_copy_from_pe(dd_wls_UUID_t *p, const dd_wls_UUID_t *p2)
{ flatbuffers_uint64_copy_from_pe(&p->hi, &p2->hi); flatbuffers_uint64_copy_from_pe(&p->lo, &p2->lo);
return p; }
__flatbuffers_build_struct(flatbuffers_, dd_wls_UUID, 16, 8, dd_wls_UUID_file_identifier, dd_wls_UUID_type_identifier)
__flatbuffers_define_fixed_array_primitives(flatbuffers_, dd_wls_UUID, dd_wls_UUID_t)

static const flatbuffers_voffset_t __dd_wls_Policy_required[] = { 0 };
typedef flatbuffers_ref_t dd_wls_Policy_ref_t;
static dd_wls_Policy_ref_t dd_wls_Policy_clone(flatbuffers_builder_t *B, dd_wls_Policy_table_t t);
Expand All @@ -57,7 +34,7 @@ static dd_wls_Policies_ref_t dd_wls_Policies_clone(flatbuffers_builder_t *B, dd_
__flatbuffers_build_table(flatbuffers_, dd_wls_Policies, 1)

#define __dd_wls_Policy_formal_args ,\
flatbuffers_string_ref_t v0, dd_wls_NodeTypeWrapper_ref_t v1, dd_wls_Action_vec_ref_t v2, dd_wls_UUID_t *v3, int64_t v4
flatbuffers_string_ref_t v0, dd_wls_NodeTypeWrapper_ref_t v1, dd_wls_Action_vec_ref_t v2, flatbuffers_string_ref_t v3, int64_t v4
#define __dd_wls_Policy_call_args ,\
v0, v1, v2, v3, v4
static inline dd_wls_Policy_ref_t dd_wls_Policy_create(flatbuffers_builder_t *B __dd_wls_Policy_formal_args);
Expand All @@ -71,17 +48,17 @@ __flatbuffers_build_table_prolog(flatbuffers_, dd_wls_Policies, dd_wls_Policies_
__flatbuffers_build_string_field(0, flatbuffers_, dd_wls_Policy_description, dd_wls_Policy)
__flatbuffers_build_table_field(1, flatbuffers_, dd_wls_Policy_rules, dd_wls_NodeTypeWrapper, dd_wls_Policy)
__flatbuffers_build_table_vector_field(2, flatbuffers_, dd_wls_Policy_actions, dd_wls_Action, dd_wls_Policy)
__flatbuffers_build_struct_field(3, flatbuffers_, dd_wls_Policy_id, dd_wls_UUID, 16, 8, dd_wls_Policy)
__flatbuffers_build_string_field(3, flatbuffers_, dd_wls_Policy_id, dd_wls_Policy)
__flatbuffers_build_scalar_field(4, flatbuffers_, dd_wls_Policy_version, flatbuffers_int64, int64_t, 8, 8, INT64_C(0), dd_wls_Policy)

static inline dd_wls_Policy_ref_t dd_wls_Policy_create(flatbuffers_builder_t *B __dd_wls_Policy_formal_args)
{
if (dd_wls_Policy_start(B)
|| dd_wls_Policy_id_add(B, v3)
|| dd_wls_Policy_version_add(B, v4)
|| dd_wls_Policy_description_add(B, v0)
|| dd_wls_Policy_rules_add(B, v1)
|| dd_wls_Policy_actions_add(B, v2)) {
|| dd_wls_Policy_actions_add(B, v2)
|| dd_wls_Policy_id_add(B, v3)) {
return 0;
}
return dd_wls_Policy_end(B);
Expand All @@ -91,11 +68,11 @@ static dd_wls_Policy_ref_t dd_wls_Policy_clone(flatbuffers_builder_t *B, dd_wls_
{
__flatbuffers_memoize_begin(B, t);
if (dd_wls_Policy_start(B)
|| dd_wls_Policy_id_pick(B, t)
|| dd_wls_Policy_version_pick(B, t)
|| dd_wls_Policy_description_pick(B, t)
|| dd_wls_Policy_rules_pick(B, t)
|| dd_wls_Policy_actions_pick(B, t)) {
|| dd_wls_Policy_actions_pick(B, t)
|| dd_wls_Policy_id_pick(B, t)) {
return 0;
}
__flatbuffers_memoize_end(B, t, dd_wls_Policy_end(B));
Expand Down
45 changes: 4 additions & 41 deletions c/src/schema/policy_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@
#define flatbuffers_extension "bin"
#endif

typedef struct dd_wls_UUID dd_wls_UUID_t;
typedef const dd_wls_UUID_t *dd_wls_UUID_struct_t;
typedef dd_wls_UUID_t *dd_wls_UUID_mutable_struct_t;
typedef const dd_wls_UUID_t *dd_wls_UUID_vec_t;
typedef dd_wls_UUID_t *dd_wls_UUID_mutable_vec_t;

typedef const struct dd_wls_Policy_table *dd_wls_Policy_table_t;
typedef struct dd_wls_Policy_table *dd_wls_Policy_mutable_table_t;
Expand All @@ -38,18 +33,6 @@ typedef const struct dd_wls_Policies_table *dd_wls_Policies_table_t;
typedef struct dd_wls_Policies_table *dd_wls_Policies_mutable_table_t;
typedef const flatbuffers_uoffset_t *dd_wls_Policies_vec_t;
typedef flatbuffers_uoffset_t *dd_wls_Policies_mutable_vec_t;
#ifndef dd_wls_UUID_file_identifier
#define dd_wls_UUID_file_identifier 0
#endif
/* deprecated, use dd_wls_UUID_file_identifier */
#ifndef dd_wls_UUID_identifier
#define dd_wls_UUID_identifier 0
#endif
#define dd_wls_UUID_type_hash ((flatbuffers_thash_t)0x23726554)
#define dd_wls_UUID_type_identifier "\x54\x65\x72\x23"
#ifndef dd_wls_UUID_file_extension
#define dd_wls_UUID_file_extension "bin"
#endif
#ifndef dd_wls_Policy_file_identifier
#define dd_wls_Policy_file_identifier 0
#endif
Expand All @@ -76,27 +59,6 @@ typedef flatbuffers_uoffset_t *dd_wls_Policies_mutable_vec_t;
#endif


/** unfortunetly flatbuffers doesnt support fixed size arrays in go so we can't use it
* the solution is to split it into two unsigned longs :(
* this should be populate after caculation, and removed prior to verification. */
struct dd_wls_UUID {
alignas(8) uint64_t hi;
alignas(8) uint64_t lo;
};
static_assert(sizeof(dd_wls_UUID_t) == 16, "struct size mismatch");

static inline const dd_wls_UUID_t *dd_wls_UUID__const_ptr_add(const dd_wls_UUID_t *p, size_t i) { return p + i; }
static inline dd_wls_UUID_t *dd_wls_UUID__ptr_add(dd_wls_UUID_t *p, size_t i) { return p + i; }
static inline dd_wls_UUID_struct_t dd_wls_UUID_vec_at(dd_wls_UUID_vec_t vec, size_t i)
__flatbuffers_struct_vec_at(vec, i)
static inline size_t dd_wls_UUID__size(void) { return 16; }
static inline size_t dd_wls_UUID_vec_len(dd_wls_UUID_vec_t vec)
__flatbuffers_vec_len(vec)
__flatbuffers_struct_as_root(dd_wls_UUID)

__flatbuffers_define_struct_scalar_field(dd_wls_UUID, hi, flatbuffers_uint64, uint64_t)
__flatbuffers_define_struct_scalar_field(dd_wls_UUID, lo, flatbuffers_uint64, uint64_t)


/** Represents a policy that contains rules and actions.
* The rules are represented as a tree structure where each node can be a leaf (with an evaluator) or a root (with child nodes). */
Expand All @@ -114,9 +76,10 @@ __flatbuffers_define_string_field(0, dd_wls_Policy, description, 0)
__flatbuffers_define_table_field(1, dd_wls_Policy, rules, dd_wls_NodeTypeWrapper_table_t, 0)
/** The actions are taken post evaluation of the policy. */
__flatbuffers_define_vector_field(2, dd_wls_Policy, actions, dd_wls_Action_vec_t, 0)
/** 128 bit UUID represented as 16 raw bytes
* this can be used to verify integrity (but NOT origin - this is not a signature!) */
__flatbuffers_define_struct_field(3, dd_wls_Policy, id, dd_wls_UUID_struct_t, 0)
/** Stable identifier for this policy, used to attribute an evaluation outcome
* back to its source. For Remote Config policies this is the rule's UUID;
* for hardcoded/built-in policies it is the sentinel "hardcoded". */
__flatbuffers_define_string_field(3, dd_wls_Policy, id, 0)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Are we sure this is backward compatible with existing policies already in flatbuffer?

@annacai21 annacai21 Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes. This would be a breaking wire-format change for any buffer where id was already populated. However, I checked both ways a Policy buffer gets built and confirmed that neither of them already populated the id field:

  1. dd-policy-engine's converters never called PolicyAddId anywhere in this repo before PR Stamp hardcoded policies with id="hardcoded" #75
  2. RC policies are compiled via dd-compile-policy from JSON, but that JSON has never contained a real id either.

Since FlatBuffers vtables mark an unset field as explicitly absent, every buffer compiled by either path so far has that slot empty, and the new reader will correctly see the field absent rather than reinterpreting old struct bytes as a string offset. This would only be unsafe if some buffer out there already had a real non-zero id, and nothing does yet.

/** used to track the version number of this policy */
__flatbuffers_define_scalar_field(4, dd_wls_Policy, version, flatbuffers_int64, int64_t, INT64_C(0))

Expand Down
42 changes: 1 addition & 41 deletions c/src/schema/policy_verifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,53 +18,13 @@
static int dd_wls_Policy_verify_table(flatcc_table_verifier_descriptor_t *td);
static int dd_wls_Policies_verify_table(flatcc_table_verifier_descriptor_t *td);

static inline int dd_wls_UUID_verify_as_root(const void *buf, size_t bufsiz)
{
return flatcc_verify_struct_as_root(buf, bufsiz, dd_wls_UUID_identifier, 16, 8);
}

static inline int dd_wls_UUID_verify_as_root_with_size(const void *buf, size_t bufsiz)
{
return flatcc_verify_struct_as_root_with_size(buf, bufsiz, dd_wls_UUID_identifier, 16, 8);
}

static inline int dd_wls_UUID_verify_as_typed_root(const void *buf, size_t bufsiz)
{
return flatcc_verify_struct_as_typed_root(buf, bufsiz, dd_wls_UUID_type_hash, 16, 8);
}

static inline int dd_wls_UUID_verify_as_typed_root_with_size(const void *buf, size_t bufsiz)
{
return flatcc_verify_struct_as_typed_root_with_size(buf, bufsiz, dd_wls_UUID_type_hash, 16, 8);
}

static inline int dd_wls_UUID_verify_as_root_with_type_hash(const void *buf, size_t bufsiz, flatbuffers_thash_t thash)
{
return flatcc_verify_struct_as_typed_root(buf, bufsiz, thash, 16, 8);
}

static inline int dd_wls_UUID_verify_as_root_with_type_hash_and_size(const void *buf, size_t bufsiz, flatbuffers_thash_t thash)
{
return flatcc_verify_struct_as_typed_root_with_size(buf, bufsiz, thash, 16, 8);
}

static inline int dd_wls_UUID_verify_as_root_with_identifier(const void *buf, size_t bufsiz, const char *fid)
{
return flatcc_verify_struct_as_root(buf, bufsiz, fid, 16, 8);
}

static inline int dd_wls_UUID_verify_as_root_with_identifier_and_size(const void *buf, size_t bufsiz, const char *fid)
{
return flatcc_verify_struct_as_root_with_size(buf, bufsiz, fid, 16, 8);
}

static int dd_wls_Policy_verify_table(flatcc_table_verifier_descriptor_t *td)
{
int ret;
if ((ret = flatcc_verify_string_field(td, 0, 0) /* description */)) return ret;
if ((ret = flatcc_verify_table_field(td, 1, 0, &dd_wls_NodeTypeWrapper_verify_table) /* rules */)) return ret;
if ((ret = flatcc_verify_table_vector_field(td, 2, 0, &dd_wls_Action_verify_table) /* actions */)) return ret;
if ((ret = flatcc_verify_field(td, 3, 16, 8) /* id */)) return ret;
if ((ret = flatcc_verify_string_field(td, 3, 0) /* id */)) return ret;
if ((ret = flatcc_verify_field(td, 4, 8, 8) /* version */)) return ret;
return flatcc_verify_ok;
}
Expand Down
Loading