Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
8194d51
feat: /v2/apis.getApi
chronark May 9, 2025
e33448f
wip
chronark May 9, 2025
8c12cff
wip
chronark May 9, 2025
263d16f
wip: the ai did ai things
chronark May 12, 2025
ff3687e
fix: v2_apis_create_api
chronark May 12, 2025
f12807e
fix: v2_apis_delete_api
chronark May 12, 2025
7e7e0d4
fix: v2_apis_delete
chronark May 12, 2025
9237bd4
fix: v2_apis_get_api
chronark May 12, 2025
b45c622
[autofix.ci] apply automated fixes
autofix-ci[bot] May 12, 2025
984aee0
wip
chronark May 12, 2025
6d7b4ff
Merge branch 'v2-api' of https://github.com/unkeyed/unkey into v2-api
chronark May 12, 2025
a2e08ab
[autofix.ci] apply automated fixes
autofix-ci[bot] May 12, 2025
674e4c0
Merge branch 'main' of https://github.com/unkeyed/unkey into v2-api
chronark May 13, 2025
66a36d5
feat: openapi /v2/keys.verifyKey
chronark May 13, 2025
921c567
feat: openapi /v2/keys.verifyKey
chronark May 13, 2025
1a68d01
feat: openapi /v2/keys.createKey
chronark May 13, 2025
44cd9cb
feat: /v2/keys.getKey
chronark May 13, 2025
0f7cc52
wip
chronark May 13, 2025
059a9cc
wip
chronark May 13, 2025
65c6de6
wip
chronark May 13, 2025
0a509c5
wip
chronark May 13, 2025
19a919b
wip
chronark May 13, 2025
aa364b8
wip
chronark May 13, 2025
02bf414
wip
chronark May 13, 2025
e49f531
wip
chronark May 13, 2025
bb3bc7e
wip
chronark May 13, 2025
2aad1fb
wip
chronark May 13, 2025
1d06a98
wip
chronark May 13, 2025
8e6bbed
wip
chronark May 13, 2025
44ce71c
wip
chronark May 13, 2025
4a0a703
wip
chronark May 14, 2025
8dad02c
test: v2_apis_create_api
chronark May 14, 2025
e8f70be
tests
chronark May 14, 2025
7952835
wip
chronark May 14, 2025
6bc00fe
fix: getidentity
chronark May 14, 2025
8f0c769
fix: tests
chronark May 14, 2025
9a819d8
wip
chronark May 15, 2025
ced8c59
wip
chronark May 15, 2025
f5b5098
wip
chronark May 15, 2025
0765511
merge
chronark Jun 3, 2025
104a564
Merge branch 'main' of https://github.com/unkeyed/unkey into v2-api
chronark Jun 9, 2025
689138c
chore: update
chronark Jun 9, 2025
f1fcdd8
chore: use new fault methods
chronark Jun 9, 2025
a2af25c
fix:
chronark Jun 9, 2025
203ccbb
fix: v2_apis_list_keys
chronark Jun 9, 2025
9c567f7
fix: v2_identities_delete_identity
chronark Jun 9, 2025
81cdc1c
fix: v2_identities_update_identity
chronark Jun 9, 2025
d4e7d2c
fix: v2_permissions_create_role
chronark Jun 9, 2025
226303f
fix: v2_permissions_create_permission
chronark Jun 9, 2025
8f3ac96
fix: v2_permissions_delete_permission
chronark Jun 9, 2025
dcff5bf
fix: v2_permissions_delte_role
chronark Jun 9, 2025
50e52d0
fix: v2_permissions_get_permission
chronark Jun 9, 2025
afa31d2
fix: v2_permissions_get_role
chronark Jun 9, 2025
f3f1f6a
fix: list roles
chronark Jun 9, 2025
32eab82
fix: v2_permissions_list_roles
chronark Jun 9, 2025
12e69e1
[autofix.ci] apply automated fixes
autofix-ci[bot] Jun 9, 2025
10fb452
fix: apis
chronark Jun 10, 2025
61ce44b
fix: set_roles
chronark Jun 10, 2025
795ca05
fix: add_roles
chronark Jun 10, 2025
87829f7
fix: v2_keys_add_permissions
chronark Jun 10, 2025
bb51bb2
fix: v2_keys_remove_permissions
chronark Jun 10, 2025
36afa1b
fix: v2_keys_set_permissions
chronark Jun 10, 2025
7368dd3
fix: v2_keys_set_permissions
chronark Jun 10, 2025
af2a6f9
fix: createkey
chronark Jun 10, 2025
ff936fd
fix: db
chronark Jun 10, 2025
549e93c
fix: remove test scenarios
chronark Jun 10, 2025
7b5c2a2
Merge branch 'v2-api' of https://github.com/unkeyed/unkey into v2-api
chronark Jun 10, 2025
e34d5ae
Merge branch 'main' into v2-api
chronark Jun 10, 2025
a1e216e
[autofix.ci] apply automated fixes
autofix-ci[bot] Jun 10, 2025
5128129
chore: remove temp files
chronark Jun 10, 2025
db5e3d8
chore: remove temp file
chronark Jun 10, 2025
579747b
Merge branch 'v2-api' of https://github.com/unkeyed/unkey into v2-api
chronark Jun 10, 2025
7add596
fix: stuff
chronark Jun 11, 2025
0fad5b6
[autofix.ci] apply automated fixes
autofix-ci[bot] Jun 11, 2025
1d32e97
fix:
chronark Jun 11, 2025
5688a94
feat: opanypiyml
chronark Jun 11, 2025
e38ad7e
feat: openapi.yaml
chronark Jun 11, 2025
36fef35
Merge branch 'v2-api' of https://github.com/unkeyed/unkey into v2-api
chronark Jun 12, 2025
44308f4
fix:
chronark Jun 12, 2025
356f23f
test: make it faster
chronark Jun 13, 2025
9f89db9
test: use random ids everywhere
chronark Jun 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
405 changes: 405 additions & 0 deletions MIGRATION_V1_TO_V2.md

Large diffs are not rendered by default.

79 changes: 40 additions & 39 deletions apps/agent/fly.production.toml
Original file line number Diff line number Diff line change
@@ -1,73 +1,74 @@
# fly.toml app configuration file generated for unkey-production-agent on 2025-06-09T13:58:09+02:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'unkey-production-agent'
primary_region = 'iad'

[build]
dockerfile = "Dockerfile"
[experimental]
cmd = ["/usr/local/bin/unkey", "agent", "--config=./config.production.json"]
cmd = ['/usr/local/bin/unkey', 'agent', '--config=./config.production.json']

[build]
dockerfile = 'Dockerfile'

[deploy]
strategy = 'canary'
max_unavailable = 10.0

[env]
PORT = '8080'
RPC_PORT = '9095'
SERF_PORT = '7373'

[http_service]
internal_port = 8080
auto_stop_machines = false
auto_start_machines = false
min_machines_running = 7
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 0
processes = ['app']

[http_service.concurrency]
type = "requests"
soft_limit = 100
type = 'requests'
hard_limit = 250
soft_limit = 100

[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
timeout = "5s"
path = "/v1/liveness"

[http_service.http_options]
[http_service.http_options.response]
pristine = true

# Serf
[[http_service.checks]]
interval = '30s'
timeout = '5s'
grace_period = '10s'
method = 'GET'
path = '/v1/liveness'

[[services]]
protocol = 'tcp'
internal_port = 7373
protocol = "tcp"

[[services.ports]]
handlers = ["tls"]
port = 7373
handlers = ['tls']


# RPC
[[services]]
protocol = 'tcp'
internal_port = 9095
protocol = "tcp"

[[services.ports]]
handlers = ["tls"]
port = 9095
handlers = ['tls']

[[restart]]
policy = 'always'
retries = 10

[[vm]]
memory = '2gb'
cpu_kind = 'shared'
cpus = 2

[deploy]
strategy = "canary"
max_unavailable = 10

[[restart]]
policy = "always"
retries = 10


[metrics]
[[metrics]]
port = 2112
path = "/metrics" # default for most prometheus exporters


[env]
PORT = "8080"
RPC_PORT = "9095"
SERF_PORT = "7373" # Spells 'serf' on a phone, I'm so funny
path = '/metrics'
100 changes: 52 additions & 48 deletions apps/agent/fly.staging.toml
Original file line number Diff line number Diff line change
@@ -1,66 +1,70 @@
# fly.toml app configuration file generated for unkey-agent-dev on 2025-06-09T13:29:12+02:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'unkey-agent-dev'
primary_region = 'iad'

[build]
dockerfile = "Dockerfile"
[experimental]
cmd = ["/usr/local/bin/unkey", "agent", "--config=./config.staging.json"]
cmd = ['/usr/local/bin/unkey', 'agent', '--config=./config.staging.json']

[build]
dockerfile = 'Dockerfile'

[deploy]
strategy = 'canary'
max_unavailable = 1.0

[env]
PORT = '8080'
RPC_PORT = '9095'
SERF_PORT = '7373'

[http_service]
internal_port = 8080
auto_start_machines = false
auto_stop_machines = false
min_machines_running = 3
processes = ['app']
internal_port = 8080
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 0
processes = ['app']

[http_service.concurrency]
type = "requests"
soft_limit = 500
hard_limit = 1000
[http_service.concurrency]
type = 'requests'
hard_limit = 1000
soft_limit = 500

[[http_service.checks]]
grace_period = "10s"
interval = "30s"
method = "GET"
timeout = "5s"
path = "/v1/liveness"
[http_service.http_options]
[http_service.http_options.response]
pristine = true

[http_service.http_options.response]
pristine = true
[[http_service.checks]]
interval = '30s'
timeout = '5s'
grace_period = '10s'
method = 'GET'
path = '/v1/liveness'

# Serf
[[services]]
internal_port = 7373
protocol = "tcp"
[[services.ports]]
handlers = ["tls"]
port = 7373
protocol = 'tcp'
internal_port = 7373

[[services.ports]]
port = 7373
handlers = ['tls']

# RPC
[[services]]
internal_port = 9095
protocol = "tcp"
[[services.ports]]
handlers = ["tls"]
port = 9095
protocol = 'tcp'
internal_port = 9095

[[services.ports]]
port = 9095
handlers = ['tls']

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1

[deploy]
strategy = "canary"
max_unavailable = 1

[env]
PORT = "8080"
RPC_PORT = "9095"
SERF_PORT = "7373" # Spells 'serf' on a phone, I'm so funny

memory = '1gb'
cpu_kind = 'shared'
cpus = 1

[metrics]
port = 2112
path = "/metrics" # default for most prometheus exporters
[[metrics]]
port = 2112
path = '/metrics'
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ description: "Attempt to modify a protected resource"

## What Happened?

This error occurs when you attempt to modify or delete a resource that is marked as protected in the Unkey system. Protected resources have special status that prevents them from being changed or removed, typically because they are system resources, defaults, or otherwise critical to proper system operation.
This error occurs when you attempt to modify or delete a resource that is marked as protected in the Unkey system. Protected resources have a special status that prevents them from being changed or removed, typically because they are system resources, defaults, or otherwise critical to proper system operation.

Common scenarios that trigger this error:
- Attempting to delete a default API or workspace
Expand Down Expand Up @@ -69,4 +69,4 @@ curl -X POST https://api.unkey.com/v2/apis.createApi \

## Related Errors
- [err:unkey:authorization:forbidden](../authorization/forbidden) - When an operation is not allowed for policy reasons
- [err:unkey:authorization:insufficient_permissions](../authorization/insufficient_permissions) - When you lack permissions for an operation
- [err:unkey:authorization:insufficient_permissions](../authorization/insufficient_permissions) - When you lack permissions for an operation
4 changes: 2 additions & 2 deletions apps/engineering/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export default async function Page(props: {

if (!page) {
notFound();
}
}

if (page.slugs.length === 0) {
if (page.slugs.length === 0) {
return (
<div className="min-h-screen border text-center -mt-16 pt-16 flex items-center w-screen justify-center ">
<div>
Expand Down
10 changes: 10 additions & 0 deletions buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: v2
plugins:
- remote: buf.build/protocolbuffers/go
out: gen
opt: paths=source_relative
- remote: buf.build/connectrpc/go:v1.16.2
out: gen
opt: paths=source_relative


10 changes: 10 additions & 0 deletions buf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: v1
breaking:
use:
- FILE
- PACKAGE
- WIRE
- WIRE_JSON
lint:
use:
- DEFAULT
2 changes: 2 additions & 0 deletions go/.golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ linters:
- usestdlibvars
- wastedassign
settings:
nestif:
min-complexity: 15
cyclop:
max-complexity: 30
package-average: 10
Expand Down
4 changes: 2 additions & 2 deletions go/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ tasks:
cmds:
- cmd: echo "Running full tests... this can take more than 30min... run 'task test-unit' for faster tests"
silent: true
- cmd: go test -failfast -timeout=60m -shuffle=on -v -json -p=10 ./... | tparse -all -progress -smallscreen
- cmd: go test -failfast -timeout=60m -shuffle=on -v -json ./... | tparse -all -progress -smallscreen
silent: true
Comment on lines +31 to 32

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Assess performance regression due to removing parallelism in test-full
Removing the -p=10 flag will serialize all integration tests and could significantly increase CI runtime. Consider isolating flaky tests, capping parallelism (e.g., -p=25), or grouping tests into stable and unstable suites to preserve throughput while avoiding intermittent failures.

🤖 Prompt for AI Agents
In go/Taskfile.yml around lines 31 to 32, the removal of the `-p=10` flag from
the `go test` command disables parallel test execution, which may cause longer
CI runtimes. To fix this, reintroduce controlled parallelism by adding a `-p`
flag with a moderate value like 2 to 5 to limit concurrency. Alternatively,
separate flaky tests into distinct groups or suites to maintain test throughput
while minimizing intermittent failures.


test-unit:
cmds:
- go test -json -race -failfast -timeout=30m -p=10 ./... | tparse -all -progress -smallscreen
- go test -json -race -failfast -timeout=30m ./... | tparse -all -progress -smallscreen

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Reevaluate parallelism strategy for unit tests
Disabling concurrency globally may slow down the developer feedback loop. If only specific packages are unstable, target them individually (e.g., -p=1 on those), or use tags/filters instead of turning off parallelism for the entire suite.

🤖 Prompt for AI Agents
In go/Taskfile.yml at line 36, the current test command disables parallelism
globally by using the -failfast flag without specifying parallelism controls,
which may slow down test execution. Adjust the command to enable parallel test
execution by removing or modifying flags that limit concurrency, and if certain
packages are unstable, apply the -p=1 flag or use tags/filters specifically for
those packages instead of disabling parallelism for all tests.


build:
cmds:
Expand Down
21 changes: 13 additions & 8 deletions go/apps/api/cancel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/unkeyed/unkey/go/pkg/port"
"github.com/unkeyed/unkey/go/pkg/testutil/containers"
"github.com/unkeyed/unkey/go/pkg/uid"
"github.com/unkeyed/unkey/go/pkg/vault/keys"
)

// TestContextCancellation verifies that the API server responds properly to context cancellation
Expand All @@ -28,6 +29,9 @@ func TestContextCancellation(t *testing.T) {
// Create a cancellable context
ctx, cancel := context.WithCancel(context.Background())

_, masterKey, err := keys.GenerateMasterKey()
require.NoError(t, err)

Comment on lines +32 to +34

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Assert the generated master-key ID as well

keys.GenerateMasterKey() returns an ID that is silently discarded. Verifying it (non-empty, unique) strengthens the test and surfaces unexpected generator regressions early.

-	_, masterKey, err := keys.GenerateMasterKey()
+	keyID, masterKey, err := keys.GenerateMasterKey()
 	require.NoError(t, err)
+	require.NotEmpty(t, keyID, "generated Vault master-key ID should not be empty")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_, masterKey, err := keys.GenerateMasterKey()
require.NoError(t, err)
keyID, masterKey, err := keys.GenerateMasterKey()
require.NoError(t, err)
require.NotEmpty(t, keyID, "generated Vault master-key ID should not be empty")
🤖 Prompt for AI Agents
In go/apps/api/cancel_test.go around lines 32 to 34, the test calls
keys.GenerateMasterKey() but discards the returned master-key ID. Modify the
test to capture this ID and add assertions to verify it is non-empty and unique
as expected. This will ensure the master-key ID generation is validated and any
regressions are caught early.

// Configure the API server
config := api.Config{
Platform: "test",
Expand All @@ -41,26 +45,27 @@ func TestContextCancellation(t *testing.T) {
DatabasePrimary: dbDsn,
DatabaseReadonlyReplica: "",
OtelEnabled: false,
VaultMasterKeys: []string{masterKey},
}

// Create a channel to receive the result of the Run function
resultCh := make(chan error, 1)

// Start the API server in a goroutine
go func() {
err := api.Run(ctx, config)
runErr := api.Run(ctx, config)

if err != nil {
if runErr != nil {
// it's really hard to get this error cause the test fails before we read from the channel
t.Logf("Error from run: %s", err.Error())
t.Logf("Error from run: %s", runErr.Error())
}
resultCh <- err
resultCh <- runErr
}()

// Wait for the server to start up
require.Eventually(t, func() bool {
res, err := http.Get(fmt.Sprintf("http://localhost:%d/v2/liveness", httpPort))
if err != nil {
res, livenessErr := http.Get(fmt.Sprintf("http://localhost:%d/v2/liveness", httpPort))
if livenessErr != nil {
return false
}
defer res.Body.Close()
Expand All @@ -75,7 +80,7 @@ func TestContextCancellation(t *testing.T) {

// Wait for the server to shut down and check the result
select {
case err := <-resultCh:
case err = <-resultCh:
// The Run function should exit without error when context is canceled
require.NoError(t, err, "API server should shut down gracefully when context is canceled")
t.Log("API server shut down successfully")
Expand All @@ -84,6 +89,6 @@ func TestContextCancellation(t *testing.T) {
}

// Verify the server is no longer responding
_, err := http.Get(fmt.Sprintf("http://localhost:%d/v2/liveness", httpPort))
_, err = http.Get(fmt.Sprintf("http://localhost:%d/v2/liveness", httpPort))
require.Error(t, err, "Server should no longer be responding after shutdown")
}
2 changes: 2 additions & 0 deletions go/apps/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ type Config struct {

// TLSConfig provides HTTPS support when set
TLSConfig *tls.Config

VaultMasterKeys []string
}

func (c Config) Validate() error {
Expand Down
Loading
Loading