Contribute to Teleport: Protobuf Events

Trace Teleport's audit event system and fix a real open source issue.

Introduction

30 Second Summary

Contributing to a large open source project feels impossible when you're staring at thousands of files with no idea where to start. The secret is finding one thread to pull on and tracing it through the entire system.

In this project, you will set up a complete Teleport contributor development environment, build the project from source, and dissect the audit event system by tracing how a Protocol Buffers definition becomes working Go code.

What You'll Build

You'll run Teleport's code generation pipeline, watch a .proto definition transform into a Go struct, and trace an audit event from its origin all the way to the exact function where it gets logged.

By the end of this project, you'll have:

  • A working Teleport build you compiled yourself, running in hot-reload mode so every Go file edit triggers an automatic rebuild within seconds.
  • The ability to read a protobuf definition, run make grpc, and point to the exact Go struct it generates.
  • A complete trace of the SSMRun audit event from its .proto file definition to the Go function where it captures AWS data.
  • Secret Mission: Implement the actual fix for GitHub issue #68771 and prepare it for pull request submission to a 20K-star project.

Are there any prerequisites?

This project assumes you have basic Linux terminal familiarity and a foundational understanding of Go. You also need Go 1.26.5, Rust, and Docker already installed on an Ubuntu Linux machine.

If you're comfortable running commands in a terminal and can read basic Go code, you're ready to start.

Before We Start

Before We Start...

Before we dive in, let's lock in what you're about to build and why it matters for your open source contribution goals.

Install Dependencies and Build Teleport from Source

You cannot contribute to Teleport without being able to build it from source on your own machine.

You already have Go, Rust, Node, and Docker installed. Three more dependencies stand between you and a successful build: libfido2 (a C library for hardware security keys), pkg-config (helps the compiler find system libraries), and buf (Teleport's protobuf compilation tool).

In this step, get ready to:
  • Install the remaining system dependencies (libfido2, pkg-config, buf).
  • Clone the Teleport repository and check out the correct branch.
  • Build the Teleport binary from source.
Install system dependencies

The Teleport build system uses pkg-config to locate C libraries on your system. It also needs libfido2 headers available (even though you will disable FIDO2 static linking later for simplicity).

  • Install libfido2-dev and pkg-config by running this command:
sudo apt-get update && sudo apt-get install -y libfido2-dev pkg-config

What does this command do?

  • libfido2-dev installs the development headers and libraries for FIDO2 hardware security key support. Teleport's Makefile can detect it via pkg-config.
  • pkg-config is a helper tool that tells the Go compiler where to find system C libraries during the build.
  • Confirm both packages installed by running:
pkg-config --modversion libfido2

You should see a version number printed (e.g. 1.12.0 or similar depending on your Ubuntu version).

Don't see a version number?

  • Make sure the apt-get install command completed without errors. Re-run it and check for any missing package messages.
  • If you see "Package libfido2 was not found", the dev package may not have installed properly. Try sudo apt-get install --reinstall libfido2-dev.

Why isn't pkg-config finding libfido2 on my system?

Now install buf, Teleport's Protocol Buffers compilation tool. Teleport pins v1.66.0 in its build configuration.

  • Install buf v1.66.0 using Go's install command:
GOBIN=/usr/local/bin go install github.com/bufbuild/buf/cmd/buf@v1.66.0

What does this command do?

This uses Go's built-in package installer to compile and install the buf binary at the exact version Teleport expects. Setting GOBIN=/usr/local/bin places the binary on your system PATH so Teleport's Makefile can find it.

  • Verify the installation by running:
buf --version

You should see 1.66.0 printed.

Seeing command not found?

  • Make sure /usr/local/bin is on your PATH. Run echo $PATH and check that it includes this directory.
  • If you see a permissions error during install, prefix the command with sudo: sudo GOBIN=/usr/local/bin go install github.com/bufbuild/buf/cmd/buf@v1.66.0.

Why can't my terminal find buf after installing it?

Clone the Teleport repository

The source code lives on GitHub. You will check out the branch/v18 branch because issue #68771's proto references match that stable branch.

  • Move to your home directory by running:
cd ~
  • Clone the Teleport repository by running:
git clone https://github.com/gravitational/teleport.git

How big is this clone?

The Teleport repository is large (2-3 GB). This download may take several minutes depending on your network speed. Let it run to completion.

  • Once the clone finishes, move into the repository and check out branch/v18 by running:
cd teleport && git checkout branch/v18

You should see a message like "Switched to branch 'branch/v18'" or "Branch 'branch/v18' set up to track remote branch".

Seeing a checkout error?

  • If you see "error: pathspec 'branch/v18' did not match", the clone may not have completed fully. Run git fetch --all and then try the checkout again.
  • Make sure you are inside the teleport directory. Run pwd to confirm your current location.

Help me fix a git checkout error when switching to branch/v18.

Build Teleport from source

Now you will compile the Teleport Go binary. The full build (make full) includes the web UI and requires Node 24.18.0. Since you have v22.22.1 and this project focuses on backend code, you will build just the Go binary instead.

  • Build the teleport binary by running this command from the repository root:
make build/teleport FIDO2=off

What does this command do?

This invokes Teleport's Makefile to compile only the Go backend binary, skipping the UI build entirely. The FIDO2=off flag disables static libfido2 linking, which avoids complex linking issues that are irrelevant to the audit event work you are doing.

The compiled binary lands at ./build/teleport inside the repository. This build takes a few minutes because Teleport is a large Go project.

Build takes a while

Expect 3-10 minutes depending on your machine. You will see compiler output scrolling by. As long as you do not see red error text, the build is progressing normally.

Before you check the result, what do you expect to see if the build succeeded?

  • Verify the build worked by running:
./build/teleport version

You should see a version string printed, confirming that the binary compiled successfully from source.

Seeing a build error?

  • If you see errors about missing libelf or libbpf, install them: sudo apt-get install -y libelf-dev libbpf-dev. Then run the make command again.
  • If you see errors about libpam, install: sudo apt-get install -y libpam0g-dev.
  • If you see "permission denied" on ./build/teleport, the binary may not be executable. Run chmod +x ./build/teleport and try again.

Help me fix my Teleport build errors.

You just built a 21K-star open source project from source on your own machine. Next up, you will use hot-reload mode to start iterating on code changes without manual rebuilds.

Run Teleport in Hot-Reload Mode

You just built the Teleport binary from source. That means you can compile the project, but right now every code change requires you to manually stop the binary, rebuild it, and restart it.

Hot-reload mode eliminates that friction. A tool called CompileDaemon watches your Go files and automatically rebuilds and restarts the binary every time you save a change. This is the daily workflow you'll use as a Teleport contributor.

In this step, get ready to:
  • Install CompileDaemon and start Teleport in hot-reload mode.
  • Trigger an automatic rebuild by editing a Go file.
  • Understand the edit-save-rebuild-restart loop for contribution work.
Install CompileDaemon and start hot-reload mode

CompileDaemon is a Go tool that monitors source files for changes, then recompiles and restarts your binary automatically. Teleport's Makefile already has a target that wires everything together.

  • Install CompileDaemon by running this command:
go install github.com/githubnemo/CompileDaemon@latest

What does this command do?

go install downloads the CompileDaemon source from GitHub, compiles it, and places the resulting binary in your $GOPATH/bin directory. The @latest suffix fetches the most recent tagged release.

  • Start Teleport in hot-reload mode by running:
make teleport-hot-reload

You'll see CompileDaemon start watching files and then Teleport begins its startup sequence. Log output scrolls in the terminal as the binary runs.

What does this Makefile target do?

make teleport-hot-reload launches CompileDaemon configured to watch all .go files in the repository. When any file changes, it rebuilds the Teleport binary and restarts the process with development flags.

Seeing a 'CompileDaemon: command not found' error?

Your $GOPATH/bin directory may not be in your system PATH. Run export PATH=$PATH:$(go env GOPATH)/bin and try again.

Help me fix CompileDaemon not being found in my PATH

Trigger a rebuild with a trivial change

Hot-reload mode is running and watching for changes. Now you'll prove that it works by editing a Go file and watching CompileDaemon react.

  • Open a second terminal window. Press **Cmd+Space** (macOS) or the **Windows** key (Windows/Linux) and type your terminal application name to open a new instance.
  • Navigate to the Teleport repository root in this new terminal.

Before you make a change, think about what you expect to happen. When you add a comment to a Go file and save it, do you think CompileDaemon will detect it immediately? How long do you think a rebuild will take?

  • Add a harmless comment to any Go file. For example, add a comment at the top of a small file by running:
sed -i '1s/^/\/\/ hot-reload test comment\n/' tool/teleport/common/usage.go

What does this command do?

This sed command inserts a comment line at the very top of tool/teleport/common/usage.go. The comment is syntactically valid Go, so it won't break the build. You could also open the file in any text editor and add the comment manually.

  • Switch back to the terminal running hot-reload mode.

Within seconds, you'll see CompileDaemon detect the file change, trigger a rebuild, and restart the Teleport binary. The terminal shows log lines indicating the recompilation and restart sequence.

Don't see a rebuild happening?

Make sure you saved the file. If you used a text editor instead of sed, confirm the save actually wrote to disk.

Check that the first terminal still shows make teleport-hot-reload running. If you accidentally closed it, re-run the command.

Help me figure out why CompileDaemon isn't detecting my file changes

Stop the process and confirm the loop
  • In the terminal running hot-reload, press **Ctrl+C** to stop CompileDaemon and the Teleport binary.

The process exits and your terminal is free again.

Why does this loop matter?

This is the feedback loop you'll use for every code change as a contributor: edit a Go file, save it, and CompileDaemon rebuilds and restarts the binary automatically. You never have to manually run make build/teleport between iterations.

When you implement the fix for issue #68771, you'll start hot-reload, make your changes, and immediately see whether they compile cleanly.

  • Clean up the test comment you added by running:
sed -i '1d' tool/teleport/common/usage.go

Your contributor workflow is locked in. You can build Teleport from source and iterate on changes without manual rebuilds. Next up, you'll dive into the protobuf definitions that power Teleport's entire audit event system.

Learn Protobuf by Exploring the Audit Event Definitions

You've proven your dev environment works. You can build Teleport from source and iterate with hot-reload. Now it's time to read the source code that defines the exact bug you're going to fix.

Every audit event in Teleport starts as a Protocol Buffers (protobuf) message definition in a .proto file. Issue #68771 lives in this layer. You need to understand how these definitions work before you can modify them.

In this step, get ready to:
  • Find the SSMRun and AzureRun messages and identify the missing field.
  • Understand protobuf syntax: messages, field numbers, types, and annotations.
  • Find SSMRun registered in the OneOf event registry.
Open the proto file and compare SSMRun to AzureRun

The file you need is over 6000 lines long. Instead of scrolling through it manually, you'll use sed to jump directly to the relevant message definitions.

  • View the SSMRun message definition by running this command:
sed -n '6306,6352p' api/proto/teleport/legacy/types/events/events.proto

You should see the SSMRun message with fields like CommandID, InstanceID, ExitCode, Status, and others up to PlatformVersion at field 13.

What does SSMRun represent?

SSMRun is the audit event Teleport emits every time it executes a command on an EC2 instance via AWS Systems Manager (SSM). It records what happened: which instance, which command, the exit code, and any output.

  • Now view the AzureRun message definition by running:
sed -n '6381,6420p' api/proto/teleport/legacy/types/events/events.proto

Look for a field called APIError in the output. You'll find it at field 8:

string APIError = 8 [(gogoproto.jsontag) = "api_error,omitempty"];

This is the field that SSMRun is missing. When an AWS SSM API call fails, the error message has nowhere to go in the event. That's issue #68771.

What is the difference between these two messages?

AzureRun has an APIError field that captures the error string when an Azure API call fails. SSMRun does not have this field. The fix is to add the same capability to SSMRun.

The SSMRun message's last field number is 13 (PlatformVersion). The new APIError field will become field 14.

Not seeing the expected messages?

Make sure you're on the branch/v18 branch. Run git branch to confirm. The line numbers reference this specific branch.

If the lines look different, the file may have shifted slightly. Run grep -n 'message SSMRun' api/proto/teleport/legacy/types/events/events.proto to find the exact starting line on your checkout.

Help me find the SSMRun message in the Teleport proto file

Understand the protobuf syntax patterns

Look back at the output from the two messages you just viewed. Several patterns repeat throughout the file.

  • Find an example of the message keyword, a field number assignment, and a gogoproto annotation in the SSMRun output by running:
sed -n '6306,6315p' api/proto/teleport/legacy/types/events/events.proto

What does each syntax element mean?

  • message defines a data structure. It maps directly to a Go struct after code generation.
  • Field numbers (= 1, = 2...) are used for binary encoding. They must never be reused or changed once assigned, even if a field is removed.
  • Types like string and int64 map directly to Go types (string and int64).
  • gogoproto annotations control Go code generation. For example, jsontag sets the JSON serialization name that appears as a Go struct tag.
  • Notice how AzureRun uses composition by embedding other message types. View the top of the AzureRun definition to see this:
sed -n '6381,6395p' api/proto/teleport/legacy/types/events/events.proto

You should see fields with types like AzureMetadata and AzureVMMetadata. These are other protobuf messages being embedded inside AzureRun. This is how protobuf achieves composition.

Why composition instead of inheritance?

Protobuf has no inheritance. Instead, you compose messages by embedding one inside another. AzureRun embeds AzureMetadata to get standard Azure fields (subscription ID, resource group) without repeating them. SSMRun similarly embeds common metadata messages for its AWS fields.

Find SSMRun in the OneOf event registry

Defining a message is only half the story. Teleport also needs to know that SSMRun is a valid event type. This registration happens in a large OneOf message near the bottom of the file that lists every possible audit event.

  • Search for SSMRun in the OneOf section by running:
grep -n 'SSMRun' api/proto/teleport/legacy/types/events/events.proto

You'll see several results. Look for the line that shows field 99:

events.SSMRun SSMRun = 99;

What is the OneOf message?

The OneOf message is Teleport's event router registry. It contains one field for every possible audit event type. When the system emits an event, it gets wrapped in this OneOf structure so the audit log knows how to serialize and deserialize it.

Every new event type must be registered here with a unique field number. If you add a new event message but forget to add it to OneOf, the event router won't know it exists.

Seeing many grep results?

The grep output will show SSMRun appearing in multiple places: the message definition itself, the OneOf registration, and possibly test fixtures. The OneOf registration is the one that shows = 99 as the field number.

Help me identify which grep result is the OneOf registration

Before you move on, take a moment to predict: what do you think happens after you edit this .proto file? Does the change automatically become Go code?

  • Confirm your understanding by running one final check:
grep -c 'message ' api/proto/teleport/legacy/types/events/events.proto

This prints the total number of protobuf message definitions in the file. You'll see a number well over 100. Every single one of those messages goes through code generation to become a Go struct.

You can now read a .proto file and understand exactly where issue #68771 lives. Next up, you'll run the code generation step that transforms these definitions into Go code.

Run Code Generation and See Proto Become Go

You now know exactly what the SSMRun and AzureRun messages look like in the proto file, and you can spot the missing APIError field.

But that .proto file is just a definition. It does not automatically become Go code. You must run a code generation step to transform it into usable Go structs. Forgetting this step is the single most common mistake new Teleport contributors make.

In this step, get ready to:
  • Run make grpc to generate Go code from all proto definitions.
  • Find the generated SSMRun Go struct and compare it to the proto definition.
  • Understand the full proto-to-Go pipeline so you never manually edit a generated file.
Run make grpc to generate Go code

The make grpc target invokes buf (the Protocol Buffers compiler you installed earlier) to read every .proto file in the repository and produce corresponding Go source files.

  • Run the code generation command from the repository root:
make grpc

This command takes several minutes. You will see output as buf processes proto files across the repository.

What does this command do?

The make grpc target delegates to the build system in build.assets/. Under the hood, it runs buf with code generation plugins (protoc-gen-go for message structs, protoc-gen-go-grpc for gRPC service stubs).

Each .proto file produces a corresponding .pb.go file containing Go structs that mirror the proto message definitions, plus marshaling and unmarshaling methods.

Seeing errors during code generation?

If you see an error about buf not being found, confirm it is installed and on your PATH by running buf --version. You should see v1.66.0.

If you see permission errors or missing dependencies, make sure your terminal is at the repository root and that you checked out the branch/v18 branch.

Help me debug a make grpc failure in the Teleport repository

Find the generated SSMRun Go struct

Now that code generation finished, the SSMRun proto message has become a Go struct somewhere in the api/types/events/ directory. Time to find it and see the transformation for yourself.

  • Search for the generated struct by running:
grep -rn "type SSMRun struct" api/types/events/

Before you look at the output, think about what you expect. The proto message SSMRun had fields like CommandID, InstanceID, ExitCode, and so on. What do you think they look like as Go struct fields?

The grep output shows you the exact file and line number where type SSMRun struct lives.

  • Open that file and scroll to the SSMRun struct definition. Examine a few fields by running:
grep -A 20 "type SSMRun struct" api/types/events/events.pb.go | head -25

How does the proto map to Go?

Each proto field became a Go struct field. The string CommandID = 2 in the proto became a CommandID field of type string in the Go struct.

Each gogoproto.jsontag annotation became a Go struct tag controlling JSON serialization. For example, the proto annotation jsontag = "command_id,omitempty" becomes the struct tag json:"command_id,omitempty" in Go.

The generated file also includes Marshal and Unmarshal methods so the struct can be serialized to and from protobuf binary format automatically.

Don't see the SSMRun struct?

If grep returns no results, make grpc may not have completed successfully. Scroll up in your terminal to check for errors during code generation.

Also confirm you are searching in the right directory. The generated file lives in api/types/events/ (not under the api/proto/ directory where the source .proto lives).

Help me find the generated SSMRun struct after running make grpc

Understand the full pipeline

You have now seen the complete code generation cycle in action. This is the workflow you will follow for every proto change as a Teleport contributor.

What is the proto-to-Go pipeline?

  • You edit a .proto file (add a field, change a type, define a new message).
  • You run make grpc from the repository root.
  • The generated .pb.go files update automatically with new struct fields, updated tags, and regenerated serialization methods.
  • The rest of the codebase imports these generated structs. When you instantiate SSMRun{} anywhere in Go, you are using the generated struct.

Never manually edit .pb.go files

Generated .pb.go files get overwritten every time you run make grpc. Any manual edits will be lost. Always make your changes in the .proto source file and regenerate.

To confirm the full picture, verify that your generated struct matches the proto. The SSMRun proto message had 13 fields (CommandID through PlatformVersion). The generated Go struct should have a corresponding field for each one, with JSON tags matching the gogoproto.jsontag annotations you saw in the proto file.

  • Confirm the field count by running:
grep -c "json:" api/types/events/events.pb.go | head -1

Why does the field count matter?

If you see the same number of fields with json: tags as you defined in the proto (plus some internal fields), you know the generation succeeded and your proto definition is faithfully represented in Go.

You now understand the engine that powers every proto-based feature in Teleport. Next up, you will trace where the SSMRun struct actually gets created and populated in Go code, pinpointing the exact location where issue #68771's fix belongs.

Trace the SSMRun Event from Creation to Audit Log

In the previous step, you ran make grpc and watched protobuf definitions transform into Go code. You now understand the full pipeline from .proto file to generated struct.

Knowing the proto definition is only half the picture. The generated SSMRun struct sits in a .pb.go file, but somewhere in the actual application code a function creates an instance of that struct and populates it with real data from AWS. Finding that location is how you will know exactly where to add the missing api_error field for issue #68771.

In this step, get ready to:
  • Find the exact Go file where the SSMRun struct is instantiated.
  • Identify that the AWS API error is available but not captured in the event.
  • Find the AzureRun pattern that shows how to capture the error.
Find where SSMRun is instantiated in Go code

The generated SSMRun struct lives in api/types/events/ but you need to find where the rest of the codebase actually creates an instance of it and fills in the fields. That is the application logic you will eventually modify.

  • Search the lib/ directory for SSMRun struct literals by running this command:
grep -r "SSMRun{" --include="*.go" lib/

What does this command do?

  • -r searches recursively through all subdirectories of lib/.
  • "SSMRun{" matches the pattern of a Go struct literal being instantiated (the type name followed by an opening brace).
  • --include="*.go" limits results to Go source files, skipping generated protobuf code, test fixtures, and other file types.

You should see output pointing to one or more files in the lib/srv/server/ package. This is Teleport's SSM installer logic, part of the discovery and auto-enrollment system.

Why lib/srv/server/?

Teleport's EC2 auto-discovery uses AWS Systems Manager (SSM) to remotely install the Teleport agent on discovered instances. The lib/srv/server/ssm_install.go file contains the installer that sends SSM commands and reports results as audit events.

Read the function and identify the missing error capture

Now that you know which file contains the SSMRun instantiation, you need to read the function and understand how it populates the struct fields from the AWS SSM API response.

  • Open the file that grep pointed to (lib/srv/server/ssm_install.go) in your editor or pager.
  • Look for the function that creates the &apievents.SSMRun{ struct literal.
  • Notice how it populates fields like CommandID, InstanceID, ExitCode, Status, StandardOutput, and StandardError from the AWS API response.
less lib/srv/server/ssm_install.go

What should I look for?

You will find two places where the SSMRun struct is created. One is in invalidSSMInstanceInstallationResult (for instances that never ran the command). The other is in getCommandStepOutcome (for instances where the command ran and returned a result).

Notice that when an AWS API error occurs (for example, the SendCommand call fails), that error is either returned as a Go error or captured in Status and StandardError. There is no dedicated APIError field being set on the event. This is the bug from issue #68771.

The SSMRun proto message currently has fields up to number 13 (PlatformVersion). No field captures the API-level error string. The error is available in the Go code but silently discarded from the audit event.

Find the AzureRun pattern to replicate

Teleport already solved this problem for Azure VM auto-discovery. The AzureRun event has an APIError field that captures the error string. You need to find this pattern so you know exactly what to replicate.

  • Search for the AzureRun struct literal in the same way by running:
grep -r "AzureRun{" --include="*.go" lib/
  • Open the file from the results and find how the APIError field gets populated.

What does the AzureRun pattern look like?

In the Azure equivalent, when the API call fails, the code captures the error with something like APIError: err.Error(). This stores the human-readable error string in the audit event so operators can see exactly what went wrong without digging through logs.

The AzureRun proto definition has: string APIError = 8 [(gogoproto.jsontag) = "api_error,omitempty"];. This is the exact pattern you will replicate for SSMRun in the Secret Mission.

Before you move on, confirm your understanding. Do you think you could name the exact file, the function, and describe what field is missing?

Grep returns no results?

  • Make sure you are running the command from the repository root directory, not from inside a subdirectory.
  • Confirm you checked out branch/v18 in a previous step. The file paths may differ on other branches.
  • Double-check the quotes around SSMRun{ and *.go. Shell expansion can interfere if the asterisk is not quoted.

Help me debug my grep command for finding SSMRun in the Teleport codebase.

You now have the complete picture. You know where SSMRun is defined (proto), where it becomes Go code (make grpc), where it is instantiated with real data (lib/srv/server/ssm_install.go), and what the fix looks like (the AzureRun pattern). In the Secret Mission, you will put all of this together and implement the actual fix for issue #68771.

Secret mission

Implement the Fix for Issue #68771

You've traced the bug. You know where it lives, what's missing, and what the fix looks like. Now it's time to write the actual code, verify it compiles and passes tests, and submit your first pull request to a 21K-star open source project following their official contribution workflow.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs entirely locally, so there are no ongoing costs.

Resources you used:

  • Teleport repository clone on your Desktop (~2-3 GB).
  • CompileDaemon Go binary (installed to ~/go/bin/).
  • System packages installed via apt: libfido2-dev and pkg-config.
  • buf binary (protobuf compiler tool).
  • GitHub fork of the Teleport repository.

Keep everything running

No action needed. Choose this if you plan to continue contributing to Teleport or want to explore other issues.

  • Your local clone, build artifacts, and installed tools remain in place for future contribution work.
  • Your GitHub fork stays linked to the upstream Teleport repository so you can pull new changes at any time.
  • CompileDaemon and buf remain available for hot-reload development and proto compilation.

Pause - I'll come back to this later

Stop any running Teleport processes to free up system resources. All files stay on disk for when you return.

  • If Teleport or CompileDaemon is still running in any terminal, press Ctrl+C to stop it.
  • Close any open terminals and editor windows pointing at the Teleport repo.
  • Everything stays on disk. When you come back, navigate to ~/Desktop/teleport and pick up where you left off.

Delete - I don't want to use this again

Remove all project resources from your machine and GitHub account. This frees up ~2-3 GB of disk space.

  • Remove the Teleport repository clone by running:
  • Remove the CompileDaemon binary by running:
rm -rf ~/Desktop/teleport
rm ~/go/bin/CompileDaemon
  • Remove the system packages you installed by running:
sudo apt remove libfido2-dev pkg-config
  • Remove the buf binary by running:
rm $(which buf)
  • Delete your GitHub fork of Teleport.
  • Go to your fork on GitHub (github.com/YOUR-USERNAME/teleport).
  • Click Settings in the top navigation bar.
  • Scroll down to the Danger Zone section.
  • Click Delete this repository and follow the confirmation prompts.

That's a Wrap!

That's a Wrap!

Nice work. You just built a 20K-star open source project from source, dissected its protobuf-based event system, and traced a real GitHub issue all the way from proto definition to the exact line of Go code that needs fixing.

You've learned how to:

  • Build Teleport from source using make build/teleport and run it in hot-reload mode for a fast edit-compile-restart development loop.
  • Read Protocol Buffer definitions, run make grpc to generate Go code, and understand the full pipeline from .proto file to generated Go struct.
  • Trace an audit event through Teleport's codebase, from its proto message definition to the Go function that instantiates it with real AWS data, identifying the exact gap described in issue #68771.
  • Secret Mission: Implement the fix for issue #68771 by adding the APIError field to the SSMRun event and submit your first PR to Teleport following their contribution workflow.

Ready to quiz yourself?