Remove pre-1.0 audit and protected request scaffolding
This commit is contained in:
@@ -38,7 +38,6 @@ func (svc *CoreService) GenerateRunDistributionForSession(sessionID string, requ
|
||||
return domain.RunDistribution{}, err
|
||||
}
|
||||
if err := validatePluginTarget(plugin, request.TargetOS); err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, "run.generate.denied", "server-instance", instance.ID, domain.AuditResultDenied, "run generation denied: unsupported target")
|
||||
return domain.RunDistribution{}, err
|
||||
}
|
||||
if deploymentNeedsCompleteRuntimeBinding(plugin, instance.Deployment) {
|
||||
@@ -47,7 +46,6 @@ func (svc *CoreService) GenerateRunDistributionForSession(sessionID string, requ
|
||||
}
|
||||
}
|
||||
if ready, reason := svc.distributionBuilderReadiness(); !ready {
|
||||
_ = svc.recordAuditEvent(user.ID, "run.generate.denied", "server-instance", instance.ID, domain.AuditResultDenied, reason)
|
||||
return domain.RunDistribution{}, validationError(reason)
|
||||
}
|
||||
|
||||
@@ -114,9 +112,6 @@ func (svc *CoreService) GenerateRunDistributionForSession(sessionID string, requ
|
||||
return domain.RunDistribution{}, validationError("distribution build idempotency key conflicts with another job")
|
||||
}
|
||||
svc.enqueueDistributionBuild(job)
|
||||
if err := svc.recordAuditEvent(user.ID, "run.generate", "server-instance", instance.ID, domain.AuditResultQueued, "queued run binary build job in the platform builder with redacted runtime key ref"); err != nil {
|
||||
return domain.RunDistribution{}, err
|
||||
}
|
||||
return domain.CopyRunDistribution(distribution), nil
|
||||
}
|
||||
|
||||
@@ -144,26 +139,22 @@ func (svc *CoreService) GenerateClientManagerDistributionForSession(sessionID st
|
||||
return domain.ClientManagerDistribution{}, err
|
||||
}
|
||||
if err := validatePluginTarget(plugin, request.TargetOS); err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, "client-manager.build.denied", "server-instance", instance.ID, domain.AuditResultDenied, "client-manager build denied: unsupported target")
|
||||
return domain.ClientManagerDistribution{}, err
|
||||
}
|
||||
profile, err := findRuntimeClientManagerProfile(plugin, request.ProfileKey)
|
||||
if err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, "client-manager.build.denied", "server-instance", instance.ID, domain.AuditResultDenied, "client-manager build denied: profile is not declared")
|
||||
return domain.ClientManagerDistribution{}, err
|
||||
}
|
||||
if strings.TrimSpace(request.SourceRevision) == "" {
|
||||
request.SourceRevision = clientManagerProfileRevision(profile)
|
||||
}
|
||||
if !clientManagerProfileSupportsTarget(profile, request.TargetOS, request.TargetArch) || request.RepositoryURL != profile.RepositoryURL || !clientManagerProfileAllowsRevision(profile, request.SourceRevision) {
|
||||
_ = svc.recordAuditEvent(user.ID, "client-manager.build.denied", "server-instance", instance.ID, domain.AuditResultDenied, "client-manager build denied: repository, revision, or target is not declared")
|
||||
return domain.ClientManagerDistribution{}, validationError("client-manager build must match the declared profile repository, revision, and target")
|
||||
}
|
||||
if err := svc.requireCompleteRuntimeBindings(user.ID, instance.ID, "client-manager.build.denied"); err != nil {
|
||||
return domain.ClientManagerDistribution{}, err
|
||||
}
|
||||
if ready, reason := svc.distributionBuilderReadiness(); !ready {
|
||||
_ = svc.recordAuditEvent(user.ID, "client-manager.build.denied", "server-instance", instance.ID, domain.AuditResultDenied, reason)
|
||||
return domain.ClientManagerDistribution{}, validationError(reason)
|
||||
}
|
||||
|
||||
@@ -271,9 +262,6 @@ func (svc *CoreService) GenerateClientManagerDistributionForSession(sessionID st
|
||||
return domain.ClientManagerDistribution{}, validationError("distribution build idempotency key conflicts with another job")
|
||||
}
|
||||
svc.enqueueDistributionBuild(job)
|
||||
if err := svc.recordAuditEvent(user.ID, "client-manager.build", "server-instance", instance.ID, domain.AuditResultQueued, "queued client-manager source build in the platform builder with redacted runtime key ref"); err != nil {
|
||||
return domain.ClientManagerDistribution{}, err
|
||||
}
|
||||
return domain.CopyClientManagerDistribution(distribution), nil
|
||||
}
|
||||
|
||||
@@ -376,9 +364,6 @@ func (svc *CoreService) ResetComponentKeyForSession(sessionID string, request do
|
||||
return domain.EncryptedComponentKey{}, err
|
||||
}
|
||||
}
|
||||
if err := svc.recordAuditEvent(user.ID, "runtime-key.reset", "server-instance", instance.ID, domain.AuditResultSuccess, "reset "+string(request.ComponentKind)+" key; previous packages revoked"); err != nil {
|
||||
return domain.EncryptedComponentKey{}, err
|
||||
}
|
||||
return domain.CopyEncryptedComponentKey(newKey), nil
|
||||
}
|
||||
|
||||
@@ -404,7 +389,6 @@ func (svc *CoreService) AuthenticateComponent(request domain.ComponentAuthentica
|
||||
}
|
||||
if key.Generation != request.Generation {
|
||||
result.Reason = "key generation is no longer current"
|
||||
_ = svc.recordAuditEvent("runtime", "runtime-key.auth", "server-instance", request.ServerInstanceID, domain.AuditResultDenied, "component authentication denied: stale generation")
|
||||
return domain.CopyComponentAuthenticationResult(result), nil
|
||||
}
|
||||
plainKey, err := svc.decryptRuntimeKey(key.EncryptedKey)
|
||||
@@ -413,7 +397,6 @@ func (svc *CoreService) AuthenticateComponent(request domain.ComponentAuthentica
|
||||
}
|
||||
if subtle.ConstantTimeCompare([]byte(plainKey), []byte(request.Key)) != 1 {
|
||||
result.Reason = "key is not current"
|
||||
_ = svc.recordAuditEvent("runtime", "runtime-key.auth", "server-instance", request.ServerInstanceID, domain.AuditResultDenied, "component authentication denied: key mismatch")
|
||||
return domain.CopyComponentAuthenticationResult(result), nil
|
||||
}
|
||||
result.Allowed = true
|
||||
@@ -523,14 +506,12 @@ func (svc *CoreService) PushRunUpdateForSession(sessionID string, request domain
|
||||
return domain.RunUpdateJob{}, err
|
||||
}
|
||||
if artifact.State != domain.ArtifactStateAvailable {
|
||||
_ = svc.recordAuditEvent(user.ID, "run.update.denied", "server-instance", instance.ID, domain.AuditResultDenied, "run update denied: artifact is unavailable")
|
||||
return domain.RunUpdateJob{}, validationError("artifact must be available")
|
||||
}
|
||||
if request.Checksum == "" {
|
||||
request.Checksum = artifact.Checksum
|
||||
}
|
||||
if request.Checksum != artifact.Checksum {
|
||||
_ = svc.recordAuditEvent(user.ID, "run.update.denied", "server-instance", instance.ID, domain.AuditResultDenied, "run update denied: checksum mismatch")
|
||||
return domain.RunUpdateJob{}, validationError("checksum must match artifact")
|
||||
}
|
||||
endpoint, err := svc.store.RunEndpoints().Get(instance.RunEndpointID)
|
||||
@@ -546,7 +527,6 @@ func (svc *CoreService) PushRunUpdateForSession(sessionID string, request domain
|
||||
}
|
||||
distribution, err := findRunDistributionForArtifact(distributions, artifact.ID)
|
||||
if err != nil || distribution.RunEndpointID != endpoint.ID || distribution.TargetOS != endpoint.Platform || distribution.TargetArch != endpoint.Architecture || distribution.Checksum != artifact.Checksum || artifact.OwnerKind != domain.ArtifactOwnerKindJob || artifact.OwnerID != distribution.BuildJobID {
|
||||
_ = svc.recordAuditEvent(user.ID, "run.update.denied", "server-instance", instance.ID, domain.AuditResultDenied, "run update denied: artifact is not an approved target-matched Run distribution")
|
||||
return domain.RunUpdateJob{}, validationError("artifact must be an approved target-matched Run distribution")
|
||||
}
|
||||
job, err := svc.CreateJob(domain.Job{
|
||||
@@ -560,7 +540,6 @@ func (svc *CoreService) PushRunUpdateForSession(sessionID string, request domain
|
||||
Progress: domain.JobProgress{Percent: 0, Message: "run self-update queued"},
|
||||
})
|
||||
if err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, "run.update.denied", "server-instance", instance.ID, domain.AuditResultDenied, "run update denied: endpoint unsupported or offline")
|
||||
return domain.RunUpdateJob{}, err
|
||||
}
|
||||
stamp := svc.now()
|
||||
@@ -598,9 +577,6 @@ func (svc *CoreService) PushRunUpdateForSession(sessionID string, request domain
|
||||
}
|
||||
return domain.RunUpdateJob{}, err
|
||||
}
|
||||
if err := svc.recordAuditEvent(user.ID, "run.update", "server-instance", instance.ID, domain.AuditResultQueued, "queued run self-update job with artifact checksum"); err != nil {
|
||||
return domain.RunUpdateJob{}, err
|
||||
}
|
||||
return domain.CopyRunUpdateJob(updateJob), nil
|
||||
}
|
||||
|
||||
@@ -625,7 +601,6 @@ func (svc *CoreService) QueueDependencyJobForSession(sessionID string, request d
|
||||
return domain.Job{}, err
|
||||
}
|
||||
if !pluginDeclares(plugin, "server.dependencies.manage") {
|
||||
_ = svc.recordAuditEvent(user.ID, "dependency.install.denied", "server-instance", instance.ID, domain.AuditResultDenied, "dependency operation denied: plugin permission is not declared")
|
||||
return domain.Job{}, forbiddenError("plugin does not declare required permission: server.dependencies.manage")
|
||||
}
|
||||
if err := svc.requireCompleteRuntimeBindings(user.ID, instance.ID, "dependency.install.denied"); err != nil {
|
||||
@@ -656,20 +631,17 @@ func (svc *CoreService) QueueDependencyJobForSession(sessionID string, request d
|
||||
}
|
||||
expectedDigest := dependencyPlanDigest(resolution, probe, plan)
|
||||
if request.Install && request.PlanDigest != expectedDigest {
|
||||
_ = svc.recordAuditEvent(user.ID, "dependency.install.denied", "server-instance", instance.ID, domain.AuditResultDenied, "dependency install denied: reviewed plan digest is stale or missing")
|
||||
return domain.Job{}, validationError("planDigest must match the current reviewed install plan")
|
||||
}
|
||||
request.PlanDigest = expectedDigest
|
||||
capability := domain.JobCapabilityDependenciesCheck
|
||||
targetKey := "dependencies/" + request.ProbeKey
|
||||
message := "dependency check queued"
|
||||
auditAction := "dependency.check"
|
||||
state := domain.DependencyStateUnknown
|
||||
if request.Install {
|
||||
capability = domain.JobCapabilityDependenciesInstall
|
||||
targetKey = "dependencies/install/" + request.InstallPlanKey
|
||||
message = "dependency install queued"
|
||||
auditAction = "dependency.install"
|
||||
state = domain.DependencyStateInstalling
|
||||
}
|
||||
job, err := svc.CreateJob(domain.Job{
|
||||
@@ -682,15 +654,11 @@ func (svc *CoreService) QueueDependencyJobForSession(sessionID string, request d
|
||||
Progress: domain.JobProgress{Percent: 0, Message: message},
|
||||
})
|
||||
if err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, auditAction+".denied", "server-instance", instance.ID, domain.AuditResultDenied, "dependency operation denied: endpoint unsupported or offline")
|
||||
return domain.Job{}, err
|
||||
}
|
||||
if err := svc.upsertDependencyStatus(instance, request, job.ID, probe.Required, state, "queued through platform job"); err != nil {
|
||||
return domain.Job{}, err
|
||||
}
|
||||
if err := svc.recordAuditEvent(user.ID, auditAction, "server-instance", instance.ID, domain.AuditResultQueued, message); err != nil {
|
||||
return domain.Job{}, err
|
||||
}
|
||||
return domain.CopyJob(job), nil
|
||||
}
|
||||
|
||||
@@ -715,12 +683,10 @@ func (svc *CoreService) QueueLogBackfillForSession(sessionID string, request dom
|
||||
return domain.Job{}, err
|
||||
}
|
||||
if !pluginSupports(plugin, domain.JobCapabilityLogsBackfill) {
|
||||
_ = svc.recordAuditEvent(user.ID, "logs.backfill.denied", "server-instance", instance.ID, domain.AuditResultDenied, "log backfill denied: plugin capability is not declared")
|
||||
return domain.Job{}, ErrForbidden
|
||||
}
|
||||
source, err := declaredFileLogSource(plugin, request.SourceKey)
|
||||
if err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, "logs.backfill.denied", "server-instance", instance.ID, domain.AuditResultDenied, "log backfill denied: log source is not declared")
|
||||
return domain.Job{}, err
|
||||
}
|
||||
if err := svc.requireCompleteRuntimeBindings(user.ID, instance.ID, "logs.backfill.denied"); err != nil {
|
||||
@@ -738,10 +704,6 @@ func (svc *CoreService) QueueLogBackfillForSession(sessionID string, request dom
|
||||
ExecutionInput: domain.JobExecutionInput{LogSource: &source},
|
||||
})
|
||||
if err != nil {
|
||||
_ = svc.recordAuditEvent(user.ID, "logs.backfill.denied", "server-instance", instance.ID, domain.AuditResultDenied, "log backfill denied: endpoint unsupported or offline")
|
||||
return domain.Job{}, err
|
||||
}
|
||||
if err := svc.recordAuditEvent(user.ID, "logs.backfill", "server-instance", instance.ID, domain.AuditResultQueued, "queued historical log backfill without log bodies in job result"); err != nil {
|
||||
return domain.Job{}, err
|
||||
}
|
||||
return domain.CopyJob(job), nil
|
||||
@@ -763,11 +725,9 @@ func declaredFileLogSource(plugin domain.GamePlugin, sourceKey string) (domain.R
|
||||
|
||||
func (svc *CoreService) validateDistributionPluginPermission(actorID string, plugin domain.GamePlugin, serverInstanceID string, permission string, deniedAction string) error {
|
||||
if plugin.Status != domain.GamePluginStatusInstalled {
|
||||
_ = svc.recordAuditEvent(actorID, deniedAction, "server-instance", serverInstanceID, domain.AuditResultDenied, "distribution operation denied: plugin is not installed")
|
||||
return forbiddenError("plugin is not installed")
|
||||
}
|
||||
if !containsString(plugin.DeclaredPermissions, permission) {
|
||||
_ = svc.recordAuditEvent(actorID, deniedAction, "server-instance", serverInstanceID, domain.AuditResultDenied, "distribution operation denied: plugin permission is not declared")
|
||||
return forbiddenError("plugin does not declare required permission: " + permission)
|
||||
}
|
||||
return nil
|
||||
@@ -1033,63 +993,6 @@ func (svc *CoreService) upsertDependencyStatus(instance domain.ServerInstance, r
|
||||
return svc.store.DependencyStatuses().Create(status)
|
||||
}
|
||||
|
||||
func (svc *CoreService) recordAuditEvent(actorID string, action string, resourceKind string, resourceID string, result domain.AuditResult, summary string) error {
|
||||
_, err := svc.recordAuditEventWithID(actorID, action, resourceKind, resourceID, result, summary)
|
||||
return err
|
||||
}
|
||||
|
||||
func (svc *CoreService) recordAuditEventWithID(actorID string, action string, resourceKind string, resourceID string, result domain.AuditResult, summary string) (string, error) {
|
||||
svc.auditMu.Lock()
|
||||
svc.auditSeq++
|
||||
seq := svc.auditSeq
|
||||
svc.auditMu.Unlock()
|
||||
|
||||
stamp := svc.now()
|
||||
event := domain.AuditEvent{
|
||||
ID: fmt.Sprintf("audit-%s-%d-%d", strings.ReplaceAll(action, ".", "-"), stamp.UnixNano(), seq),
|
||||
ActorID: actorID,
|
||||
Action: action,
|
||||
ResourceKind: resourceKind,
|
||||
ResourceID: resourceID,
|
||||
Result: result,
|
||||
Summary: safeBridgeReason(summary),
|
||||
CreatedAt: stamp,
|
||||
}
|
||||
if err := validator.ValidateAuditEvent(event); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := svc.store.AuditEvents().Create(event); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return event.ID, nil
|
||||
}
|
||||
|
||||
func (svc *CoreService) auditArtifactDownload(sessionID string, artifact domain.Artifact) error {
|
||||
user, err := svc.GetCurrentUser(sessionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runDistributions, err := svc.store.RunDistributions().List(domain.RunDistributionFilter{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, distribution := range runDistributions {
|
||||
if distribution.ArtifactID == artifact.ID {
|
||||
return svc.recordAuditEvent(user.ID, "run.download", "server-instance", distribution.ServerInstanceID, domain.AuditResultSuccess, "downloaded run package artifact with redacted runtime key ref")
|
||||
}
|
||||
}
|
||||
clientDistributions, err := svc.store.ClientManagerDistributions().List(domain.ClientManagerDistributionFilter{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, distribution := range clientDistributions {
|
||||
if distribution.ArtifactID == artifact.ID {
|
||||
return svc.recordAuditEvent(user.ID, "client-manager.download", "server-instance", distribution.ServerInstanceID, domain.AuditResultSuccess, "downloaded client-manager package artifact with redacted runtime key ref")
|
||||
}
|
||||
}
|
||||
return svc.recordAuditEvent(user.ID, "artifact.download", string(artifact.OwnerKind), artifact.OwnerID, domain.AuditResultSuccess, "downloaded platform artifact")
|
||||
}
|
||||
|
||||
func validatePluginTarget(plugin domain.GamePlugin, targetOS string) error {
|
||||
if len(plugin.SupportedOS) == 0 || containsString(plugin.SupportedOS, targetOS) {
|
||||
return nil
|
||||
@@ -1251,7 +1154,6 @@ func (svc *CoreService) requireCompleteRuntimeBindings(actorID string, serverIns
|
||||
if complete {
|
||||
return nil
|
||||
}
|
||||
_ = svc.recordAuditEvent(actorID, deniedAction, "server-instance", serverInstanceID, domain.AuditResultDenied, "operation denied: "+reason)
|
||||
return validationError(reason)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user