-
Notifications
You must be signed in to change notification settings - Fork 609
feat: mostly just duplicate audit logs and other clickhouse stuff #2134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| -- +goose up | ||
chronark marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| CREATE TABLE default.raw_telemetry_sdks_v1( | ||
| -- the api request id, so we can correlate the telemetry with traces and logs | ||
| request_id String, | ||
|
|
||
| -- unix milli | ||
| time Int64, | ||
|
|
||
| -- ie: node@20 | ||
| runtime String, | ||
| -- ie: vercel | ||
| platform String, | ||
|
|
||
| -- ie: [ "@unkey/api@1.2.3", "@unkey/ratelimit@4.5.6" ] | ||
| versions Array(String) | ||
| ) | ||
| ENGINE = MergeTree() | ||
| ORDER BY (request_id, time) | ||
| ; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| -- +goose up | ||
| CREATE TABLE default.key_verifications_per_day_v1 | ||
| ( | ||
| time DateTime, | ||
| workspace_id String, | ||
| key_space_id String, | ||
| identity_id String, | ||
| key_id String, | ||
| outcome LowCardinality(String), | ||
| count AggregateFunction(count, UInt64) | ||
| ) | ||
| ENGINE = AggregatingMergeTree() | ||
| ORDER BY (workspace_id, key_space_id, time, identity_id, key_id) | ||
| ; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| -- +goose up | ||
| CREATE MATERIALIZED VIEW default.mv_key_verifications_per_day_v1 TO default.key_verifications_per_day_v1 AS | ||
| SELECT | ||
| workspace_id, | ||
| key_space_id, | ||
| identity_id, | ||
| key_id, | ||
| outcome, | ||
| countState() as count, | ||
| toStartOfDay(fromUnixTimestamp64Milli(time)) AS time | ||
| FROM default.raw_key_verifications_v1 | ||
| GROUP BY | ||
| workspace_id, | ||
| key_space_id, | ||
| identity_id, | ||
| key_id, | ||
| outcome, | ||
| time | ||
| ; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -41,6 +41,19 @@ export class Analytics { | |||||||||||||||||
| this.clickhouse = opts.clickhouse ? new ch.Client({ url: opts.clickhouse.url }) : new ch.Noop(); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| public get insertSdkTelemetry() { | ||||||||||||||||||
| return this.clickhouse.insert({ | ||||||||||||||||||
| table: "default.raw_telemetry_sdks_v1", | ||||||||||||||||||
| schema: z.object({ | ||||||||||||||||||
| request_id: z.string(), | ||||||||||||||||||
| time: z.number().int(), | ||||||||||||||||||
| runtime: z.string(), | ||||||||||||||||||
| platform: z.string(), | ||||||||||||||||||
| versions: z.array(z.string()), | ||||||||||||||||||
| }), | ||||||||||||||||||
| }); | ||||||||||||||||||
| } | ||||||||||||||||||
| //tinybird, to be removed | ||||||||||||||||||
| public get ingestSdkTelemetry() { | ||||||||||||||||||
| return this.writeClient.buildIngestEndpoint({ | ||||||||||||||||||
| datasource: "sdk_telemetry__v1", | ||||||||||||||||||
|
|
@@ -54,7 +67,8 @@ export class Analytics { | |||||||||||||||||
| }); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| public ingestUnkeyAuditLogs(logs: MaybeArray<UnkeyAuditLog>) { | ||||||||||||||||||
| //tinybird | ||||||||||||||||||
| public ingestUnkeyAuditLogsTinybird(logs: MaybeArray<UnkeyAuditLog>) { | ||||||||||||||||||
| return this.writeClient.buildIngestEndpoint({ | ||||||||||||||||||
| datasource: "audit_logs__v2", | ||||||||||||||||||
| event: auditLogSchemaV1 | ||||||||||||||||||
|
|
@@ -78,7 +92,8 @@ export class Analytics { | |||||||||||||||||
| })(logs); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| public get ingestGenericAuditLogs() { | ||||||||||||||||||
| //tinybird | ||||||||||||||||||
| public get ingestGenericAuditLogsTinybird() { | ||||||||||||||||||
| return this.writeClient.buildIngestEndpoint({ | ||||||||||||||||||
| datasource: "audit_logs__v2", | ||||||||||||||||||
| event: auditLogSchemaV1.transform((l) => ({ | ||||||||||||||||||
|
|
@@ -92,7 +107,7 @@ export class Analytics { | |||||||||||||||||
| })), | ||||||||||||||||||
| }); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| //tinybird | ||||||||||||||||||
| public get ingestRatelimit() { | ||||||||||||||||||
| return this.writeClient.buildIngestEndpoint({ | ||||||||||||||||||
| datasource: "ratelimits__v2", | ||||||||||||||||||
|
|
@@ -146,7 +161,7 @@ export class Analytics { | |||||||||||||||||
| }), | ||||||||||||||||||
| }); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // replaced by insertKeyVerification | ||||||||||||||||||
| public get ingestKeyVerification() { | ||||||||||||||||||
|
Comment on lines
+164
to
165
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider proper deprecation of The comment indicates that this method has been replaced by To address this:
Here's a suggested change: - // replaced by insertKeyVerification
+ /**
+ * @deprecated This method has been replaced by `insertKeyVerification`.
+ * Please use `insertKeyVerification` for all new code.
+ * This method will be removed in a future version.
+ */
public get ingestKeyVerification() {Additionally, you might want to add a console warning when this method is called to alert developers of its deprecated status. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||
| return this.writeClient.buildIngestEndpoint({ | ||||||||||||||||||
| datasource: "key_verifications__v2", | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,106 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { Context } from "@/pkg/hono/app"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { auditLogSchemaV1, unkeyAuditLogEvents } from "@unkey/schema/src/auditlog"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { type Transaction, schema } from "./db"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { newId } from "@unkey/id"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { z } from "zod"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { UnkeyAuditLog } from "./analytics"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export async function insertUnkeyAuditLog( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c: Context, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tx: Transaction | undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auditLogs: UnkeyAuditLog | Array<UnkeyAuditLog>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const schema = auditLogSchemaV1.merge( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| z.object({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event: unkeyAuditLogEvents, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auditLogId: z.string().default(newId("auditLog")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bucket: z.string().default("unkey_mutations"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| time: z.number().default(Date.now()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+21
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid variable shadowing of The local variable Apply this diff to rename the local variable: - const schema = auditLogSchemaV1.merge(
+ const validationSchema = auditLogSchemaV1.merge(Update its usage accordingly: - arr.map((l) => schema.parse(l)),
+ arr.map((l) => validationSchema.parse(l)),
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const arr = Array.isArray(auditLogs) ? auditLogs : [auditLogs]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return insertGenericAuditLogs( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tx, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arr.map((l) => schema.parse(l)), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export async function insertGenericAuditLogs( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c: Context, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tx: Transaction | undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auditLogs: z.infer<typeof auditLogSchemaV1> | z.infer<typeof auditLogSchemaV1>[], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const arr = Array.isArray(auditLogs) ? auditLogs : [auditLogs]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (arr.length === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { cache, logger, db } = c.get("services"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const log of arr) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { val: bucket, err } = await cache.auditLogBucketByWorkspaceIdAndName.swr( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [log.workspaceId, log.bucket].join(":"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const bucket = await (tx ?? db.primary).query.auditLogBucket.findFirst({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| where: (table, { eq, and }) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and(eq(table.workspaceId, log.workspaceId), eq(table.name, log.bucket)), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!bucket) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return undefined; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: bucket.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (err) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error("Could not find audit log bucket for workspace", { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workspaceId: log.workspaceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| error: err.message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!bucket) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| logger.error("Could not find audit log bucket for workspace", { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workspaceId: log.workspaceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+69
to
+73
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enhance error logging to include bucket name When logging the error for a missing audit log bucket, consider including the bucket name to provide more context for debugging. Apply this diff to include the bucket name in the log: logger.error("Could not find audit log bucket for workspace", {
workspaceId: log.workspaceId,
+ bucket: log.bucket,
});📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const auditLogId = newId("auditLog"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await (tx ?? db.primary).insert(schema.auditLog).values({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: auditLogId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workspaceId: log.workspaceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bucketId: bucket.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event: log.event, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| time: log.time, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: log.description ?? "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| remoteIp: log.context?.location, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userAgent: log.context?.userAgent, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actorType: log.actor.type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actorId: log.actor.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actorName: log.actor.name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actorMeta: log.actor.meta, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+75
to
+92
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use provided In Apply this diff to use - const auditLogId = newId("auditLog");
+ const auditLogId = log.auditLogId || newId("auditLog");📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await (tx ?? db.primary).insert(schema.auditLogTarget).values( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| log.resources.map((r) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workspaceId: log.workspaceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bucketId: bucket.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auditLogId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| displayName: r.name ?? "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: r.type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: r.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: r.name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| meta: r.meta, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,6 +1,7 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { App } from "@/pkg/hono/app"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { createRoute, z } from "@hono/zod-openapi"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { insertUnkeyAuditLog } from "@/pkg/audit"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { rootKeyAuth } from "@/pkg/auth/root_key"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { UnkeyApiError, openApiErrorResponses } from "@/pkg/errors"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { schema } from "@unkey/db"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -227,7 +228,28 @@ export const registerLegacyKeysCreate = (app: App) => | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deletedAt: null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await analytics.ingestUnkeyAuditLogs({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await analytics.ingestUnkeyAuditLogsTinybird({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workspaceId: authorizedWorkspaceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actor: { type: "key", id: rootKeyId }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event: "key.create", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description: `Created ${keyId}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| resources: [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: "key", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: keyId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: "keyAuth", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: api.keyAuthId!, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { type: "api", id: api.id }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| context: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| location: c.get("location"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userAgent: c.get("userAgent"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await insertUnkeyAuditLog(c, tx, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+231
to
+252
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Refactor to eliminate duplicated audit logging code The calls to Apply this diff to refactor the code: + const auditLogData = {
+ workspaceId: authorizedWorkspaceId,
+ actor: { type: "key", id: rootKeyId },
+ event: "key.create",
+ description: `Created ${keyId}`,
+ resources: [
+ {
+ type: "key",
+ id: keyId,
+ },
+ {
+ type: "keyAuth",
+ id: api.keyAuthId!,
+ },
+ { type: "api", id: api.id },
+ ],
+ context: {
+ location: c.get("location"),
+ userAgent: c.get("userAgent"),
+ },
+ };
- await analytics.ingestUnkeyAuditLogsTinybird({
- workspaceId: authorizedWorkspaceId,
- actor: { type: "key", id: rootKeyId },
- event: "key.create",
- description: `Created ${keyId}`,
- resources: [
- {
- type: "key",
- id: keyId,
- },
- {
- type: "keyAuth",
- id: api.keyAuthId!,
- },
- { type: "api", id: api.id },
- ],
- context: {
- location: c.get("location"),
- userAgent: c.get("userAgent"),
- },
- });
+ await analytics.ingestUnkeyAuditLogsTinybird(auditLogData);
- await insertUnkeyAuditLog(c, tx, {
- workspaceId: authorizedWorkspaceId,
- actor: { type: "key", id: rootKeyId },
- event: "key.create",
- description: `Created ${keyId}`,
- resources: [
- {
- type: "key",
- id: keyId,
- },
- {
- type: "keyAuth",
- id: api.keyAuthId!,
- },
- { type: "api", id: api.id },
- ],
- context: {
- location: c.get("location"),
- userAgent: c.get("userAgent"),
- },
- });
+ await insertUnkeyAuditLog(c, tx, auditLogData);📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workspaceId: authorizedWorkspaceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| actor: { type: "key", id: rootKeyId }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event: "key.create", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New time-based suffix introduced without documentation.
The example has been updated to use '_per_hour', which is a new time-based suffix not mentioned in the "Aggregation Suffixes" section. Consider adding '_per_hour' to the list of suffixes in that section for completeness and consistency.