diff --git a/.github/workflows/license.sh b/.github/workflows/license.sh
new file mode 100755
index 0000000..03ee294
--- /dev/null
+++ b/.github/workflows/license.sh
@@ -0,0 +1,35 @@
+LICENSE_HEADER="\
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see ."
+
+# Check for two newlines after the license header
+LICENSE_HEADER_LEN=$(("${#LICENSE_HEADER}" + 2))
+
+exit_code=0
+
+for file in $(git ls-files -- '*.rs' '*.h' '*.hpp' '*.c' '*.cpp'); do
+ contents=$(head -c $LICENSE_HEADER_LEN "$file")
+
+ if [ "$contents" == "$LICENSE_HEADER" ]; then
+ continue
+ fi
+
+ exit_code=$((exit_code + 1))
+
+ echo "$file" >&2
+done
+
+exit $exit_code
+
diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml
new file mode 100644
index 0000000..eea1d5e
--- /dev/null
+++ b/.github/workflows/license.yml
@@ -0,0 +1,20 @@
+name: License
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+ workflow_dispatch:
+ workflow_call:
+
+jobs:
+ check-license:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Check licenses
+ run: .github/workflows/license.sh
+
diff --git a/bpf/src/bpf/cpuutil.bpf.c b/bpf/src/bpf/cpuutil.bpf.c
index 0aac5c4..4aad957 100644
--- a/bpf/src/bpf/cpuutil.bpf.c
+++ b/bpf/src/bpf/cpuutil.bpf.c
@@ -1,3 +1,18 @@
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
#include "vmlinux.h"
#include
#include
diff --git a/bpf/src/bpf/nettrack.bpf.c b/bpf/src/bpf/nettrack.bpf.c
index 36dc3c4..2fdbec1 100644
--- a/bpf/src/bpf/nettrack.bpf.c
+++ b/bpf/src/bpf/nettrack.bpf.c
@@ -1,3 +1,18 @@
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
#include "vmlinux.h"
#include
#include
@@ -144,4 +159,4 @@ int handle_boundary_event(void *ctx)
submit_net_event(stats, now);
return 0;
-}
\ No newline at end of file
+}
diff --git a/bpf/src/bpf/perfcounter.bpf.c b/bpf/src/bpf/perfcounter.bpf.c
index 07361c7..06a19f9 100644
--- a/bpf/src/bpf/perfcounter.bpf.c
+++ b/bpf/src/bpf/perfcounter.bpf.c
@@ -1,3 +1,18 @@
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
#include "vmlinux.h"
#include
#include
@@ -68,4 +83,4 @@ int perfcounter_timer(struct bpf_perf_event_data *ctx) {
bpf_ringbuf_submit(event, 0);
return 0;
-}
\ No newline at end of file
+}
diff --git a/bpf/src/bpf/profiler.bpf.c b/bpf/src/bpf/profiler.bpf.c
index 40a10b8..eb91858 100644
--- a/bpf/src/bpf/profiler.bpf.c
+++ b/bpf/src/bpf/profiler.bpf.c
@@ -1,3 +1,18 @@
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
#include "vmlinux.h"
#include
#include
@@ -96,4 +111,4 @@ int profiler_perf_event(struct bpf_perf_event_data *ctx) {
bpf_ringbuf_submit(event, 0);
return 0;
-}
\ No newline at end of file
+}
diff --git a/bpf/src/bpf/schedtrace.bpf.c b/bpf/src/bpf/schedtrace.bpf.c
index 508180f..8e77e7f 100644
--- a/bpf/src/bpf/schedtrace.bpf.c
+++ b/bpf/src/bpf/schedtrace.bpf.c
@@ -1,3 +1,18 @@
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
#include "vmlinux.h"
#include
#include
diff --git a/bpf/src/bpf/threadtrack.bpf.c b/bpf/src/bpf/threadtrack.bpf.c
index ce7e5d1..38c11a7 100644
--- a/bpf/src/bpf/threadtrack.bpf.c
+++ b/bpf/src/bpf/threadtrack.bpf.c
@@ -1,3 +1,18 @@
+// Copyright (C) 2025 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
#include "vmlinux.h"
#include
#include
@@ -89,4 +104,4 @@ int handle_prctl_setname(struct trace_event_raw_sys_enter* ctx)
bpf_ringbuf_submit(e, 0);
return 0;
-}
\ No newline at end of file
+}