mirror of
https://github.com/SigNoz/signoz.git
synced 2026-06-20 15:20:31 +01:00
* feat(resource): initial commit
* feat(resource): add related resources
* feat(resource): audit cleanup
* refactor(resource): set audit category on resource defs; drop MustNew/validate
- Set Category (access_control) on every service account and role ResourceDef
so audit events carry signoz.audit.action_category
- Remove MustNewResourceDef/MustNewResourcesDef and validate(); registration
via plain ResourceDef literals again. Validation to be revisited separately
* feat(audit): emit audit events only for mutating verbs
- Add coretypes.Verb.IsMutation() (create/update/delete/attach/detach)
- Audit skips read/list defs (they remain for authz); failed and denied
mutations still emit with Outcome=failure
* feat(audit): mirror attach/detach audit on both ends for role↔service account
Role def on SetRole/DeleteRole now carries Related=ServiceAccount so each
permission-checked end emits its own event (serviceaccount.attached to role
and role.attached to serviceaccount), matching the both-ends authz model.
* refactor(resource): co-locate resolved context in handler; slice-of-pointers accessor
Move the resolved-resource context plumbing (resolvedKey, accessors) out of
the resource middleware and into pkg/http/handler next to ResolvedResource, so
type and accessor live in one package (matching the authtypes/ctxtypes
convention) and consumers import a single package.
- Store []*ResolvedResource instead of *[]ResolvedResource; in-place response-id
finalization still works via the element pointers.
- ResolvedResourcesFromContext returns an error (errCodeResolvedResourcesNotFound)
instead of a bool; authz surfaces it, audit treats absence as a no-op.
- Drop the now-dead authz Check/CheckAll/AuthZCheckGroup helpers superseded by
CheckResources.
* refactor(resource): unify id resolution into a single phase-driven mechanism
Replace the two-shaped id mechanism (a resolved string plus a stashed
responseID extractor, decided by resolveID's magic tuple and a zero-value
sentinel) with one retained extractor whose phase decides when it runs.
- ResolvedResource/ResolvedRelated keep idExtractor (renamed from responseID);
it is run in its declared phase, never re-run.
- ResourceIDExtractor gains isPhase + runFor; ResolvedResource gains resolve,
called once per phase (request by the resource middleware, response by audit).
- resolveID and resolveRelated(ec) are gone; FinalizeResponseIDs collapses to a
single resolve(phaseResponse) call. Request and response resolution are now
symmetric.
* refactor(resource): split resourcedef.go along its logical seams
Break the ~320-line resourcedef.go into cohesive files within the handler
package (pure relocation, no behavior or API change):
- extractor.go — extraction: ExtractorContext, phases, extractors + constructors
- resourcedef.go — declaration: ResourceDef/ResourcesDef/RelatedResource/
ResourceSpec + their functions (resolveRequest, ResolveRequest)
and the selectors
- resolved_resource.go — resolved types + their functions (resolve,
newResolvedRelated, FinalizeResponseIDs, HasResponseIDs)
- resolved_context.go — context plumbing (resolvedKey + accessors)
Each file's imports narrow to its concern; mux/gjson are now confined to
extractor.go.
* refactor(resource): extract selectors into selector.go
Move SelectorFunc + WildcardSelector/IDSelector (and the errCode they use)
out of resourcedef.go into selector.go. Pure relocation, no behavior change:
resourcedef.go now holds only the route-author declaration types and narrows
its imports to audittypes + coretypes.
* refactor(resource): extract ResourceSpec into resource_spec.go
Move the sealed ResourceSpec interface out of resourcedef.go into its own
file. Pure relocation, no behavior change.
* refactor(resource): split ResourcesDef into resourcesdef.go
Move the fan-out ResourcesDef (struct + sealResourceSpec/resolveRequest) out
of resourcedef.go into its own file. resourcedef.go keeps ResourceDef, the
shared RelatedResource, and the ResolveRequest orchestrator. Pure relocation,
no behavior change.
* refactor(resource): move RelatedResource and ResolveRequest into resource_spec.go
Cluster the spec contract together: the shared RelatedResource type and the
ResolveRequest orchestrator (over []ResourceSpec) join the ResourceSpec
interface. resourcedef.go now holds only ResourceDef. Pure relocation, no
behavior change.
* refactor(resource): seal ResourceSpec via resolveRequest alone
Drop the redundant sealResourceSpec() marker method; the unexported
resolveRequest already prevents implementations outside the package.
* feat(resource): scaffold coretypes-based resolved model
Introduce the referenceable, coretypes-resident resource model (additive;
the existing ResourceDef path is untouched and the build stays green):
- coretypes: ExtractorContext + ExtractPhase + ResourceIDExtractor/
ResourceIDsExtractor (extractor machinery moved out of handler; handler keeps
only the mux/gjson constructors).
- coretypes: SelectorFunc (now (ctx, resource, id, orgID) to stay cycle-free) +
WildcardSelector/IDSelector.
- coretypes: ResolvedResource + ResolvedResourceWithTargetResource interfaces,
their concrete types with two-phase fill (request ids at construction,
response ids via ResolveResponse), and the resolved-context accessors.
- handler: the three explicit declaration types — BasicResourceDef,
AttachDetachSiblingResourceDef, AttachDetachParentChildResourceDef.
Wiring (defs -> ResolveRequest, middleware, route migration) follows next.
* refactor(resource): wire the coretypes resolved model end-to-end
Cut the resource middleware over to the coretypes-resident resolved model and
the explicit declaration types, replacing the generic ResourceDef/ResourcesDef.
- handler: ResourceDef is now a sealed interface (unexported resolveRequest)
implemented by BasicResourceDef / AttachDetachSiblingResourceDef /
AttachDetachParentChildResourceDef, all consolidated into resourcedef.go.
Removed the old generic defs, the handler-side resolved/selector/context
(moved to coretypes), and the dead AuditDef.
- coretypes: ActionCategory moved here; Category() exposed on the resolved
interface (declared on the def, read by audit; no kind-based derivation).
- middleware: authz does M+N absolute checks (source always, sibling target
too, parent-child child never) via the resolved selectors; audit type-switches
on the resolved interface to emit per resource / per relationship.
- authz forbidden message is now AWS-style: principal is not authorized to
perform <kind>:<verb> on resource "<id>".
- routes: service account + role routes migrated to the explicit defs;
roleSelector takes orgID.
Note: resourcedef_test.go (old API) removed; new tests to follow.
* feat(resource): instrument query-range with telemetry resource authz
Authorize /api/v5/query_range at the telemetry-resource level, derived from the
request body rather than a path/body id:
- coretypes: ResourceExtractor now yields []ResourceWithID (resource + id), and
TelemetrySignalSource maps each query's spec.signal+spec.source to a telemetry
resource (via TelemetryResourceForSignalSource) and reads a per-query id — one
entry per query, no de-duplication, so repeated signals each get their own
resource + id.
- handler: TelemetryResourceDef fans out one resolved resource per query through
NewResolvedResourceWithID; resolveRequest returns a slice to allow fan-out.
- The extractor model (types + constructors + ResourceExtractor) now lives wholly
in coretypes (handler/extractor.go removed); coretypes gains mux/gjson.
- querier route: ViewAccess -> CheckResources + the telemetry def (spec.name is a
placeholder id; the owner picks the real field).
Carries the in-progress removal of Verb.IsMutation and its audit mutation-gate,
so audit currently emits per resolved resource regardless of verb (to revisit).
* feat(resource): instrument planned-maintenance routes + tidy resolved id handling
- ruler.go: downtime_schedules routes move from ViewAccess/EditAccess to
CheckResources with resource defs — Basic for list/read/create/update/delete on
PlannedMaintenance, plus a sibling Attach (schedule <-> the rules in alertIds)
on create/update so both the schedule and each rule are authz-checked.
- coretypes: SourceIDs/TargetIDs return a single empty id when there are none, so
collection-level access lives in the resolved value; authz.checkResource drops
its empty-id shim and just iterates.
- readability: expand crammed multi-arg signatures and calls (checkResource,
NewResolvedResource/WithID, forbidden errors.Newf, telemetry mapping) to one
argument per line.
* refactor(resource): drop query-range/planned-maintenance instrumentation; mirror sibling audit
- Revert /api/v5/query_range and downtime_schedules routes to ViewAccess/EditAccess
and remove the telemetry-resource scaffolding that only query-range consumed
(TelemetryResourceDef, TelemetrySignalSource, TelemetryResourceForSignalSource,
ResourceExtractor/ResourceWithID, NewResolvedResourceWithID).
- audit: a sibling attach/detach now emits the event from both ends, matching the
both-ends authz model (parent-child stays one-directional).
- Strip non-essential doc/inline comments across the resource middleware files.
* refactor(coretypes): fold extractor/selector _func files into their concept files
- Merge extractor_func.go + extractor_context.go into extractor.go, and
selector_func.go into selector.go, matching the type.go/object.go/verb.go
convention of keeping a type with its constructors and helpers.
- Order each file const/var -> type -> func (also reorders action_category.go).
* feat(resource): capture response body only when an id is resolved from it
- Restore the capture gate lost in the coretypes move: ResolvedResource gains an
unexported hasResponsePhase(), and ShouldCaptureResponseBody(ctx) drives the
audit middleware so the body is buffered only when some resolved resource reads
an id out of it (e.g. a create), not for every resource-declared route.
- Add ResourceIDsExtractor.IsPhase (mirroring ResourceIDExtractor) and reuse it.
- Fold resolved_context.go into resolved.go.
---------
Co-authored-by: grandwizard28 <vibhupandey28@gmail.com>